[IRTranslator] Use a single virtual register to represent any Value.
authorQuentin Colombet <qcolombet@apple.com>
Thu, 11 Feb 2016 21:48:32 +0000 (21:48 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Thu, 11 Feb 2016 21:48:32 +0000 (21:48 +0000)
PR26161.

llvm-svn: 260602

llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
llvm/include/llvm/CodeGen/GlobalISel/Types.h
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

index bc74513..d741412 100644 (file)
@@ -49,15 +49,11 @@ public:
   static char ID;
 
 private:
-  // Interface used to lower the everything related to calls.
+  /// Interface used to lower the everything related to calls.
   const TargetLowering *TLI;
-  // Mapping of the values of the current LLVM IR function
-  // to the related virtual registers.
-  // We need several virtual registers for the lowering of things
-  // like structures. Right now, this is just a list of virtual
-  // registers, but we would need to encapsulate that in a higher
-  // level class.
-  ValueToVRegs ValToVRegs;
+  /// Mapping of the values of the current LLVM IR function
+  /// to the related virtual registers.
+  ValueToVReg ValToVReg;
   // Constants are special because when we encounter one,
   // we do not know at first where to insert the definition since
   // this depends on all its uses.
@@ -116,7 +112,7 @@ private:
   void finalize();
 
   /// Get the sequence of VRegs for that \p Val.
-  const VRegsSequence &getOrCreateVRegs(const Value *Val);
+  unsigned getOrCreateVReg(const Value *Val);
 
   MachineBasicBlock &getOrCreateBB(const BasicBlock *BB);
 
index 9892a79..879091d 100644 (file)
 
 namespace llvm {
 
-typedef SmallVector<unsigned, 1> VRegsSequence;
-
-/// Map a value to virtual registers.
-/// We must support several virtual registers for a value.
-/// Indeed each virtual register is mapped to one EVT, but a value
-/// may span over several EVT when it is a type representing a structure.
-/// In that case the value will be break into EVTs.
+/// Map a value to a virtual register.
+/// For now, we chose to map aggregate types to on single virtual
+/// register. This might be revisited if it turns out to be inefficient.
+/// PR26161 tracks that.
 /// Note: We need to expose this type to the target hooks for thing like
 /// ABI lowering that would be used during IRTranslation.
-typedef DenseMap<const Value *, VRegsSequence> ValueToVRegs;
+typedef DenseMap<const Value *, unsigned> ValueToVReg;
 
 } // End namespace llvm.
 #endif
index 8b93f45..ffbda5b 100644 (file)
@@ -30,10 +30,10 @@ char IRTranslator::ID = 0;
 IRTranslator::IRTranslator() : MachineFunctionPass(ID), MRI(nullptr) {
 }
 
-const VRegsSequence &IRTranslator::getOrCreateVRegs(const Value *Val) {
-  VRegsSequence &ValRegSequence = ValToVRegs[Val];
+unsigned IRTranslator::getOrCreateVReg(const Value *Val) {
+  unsigned &ValReg = ValToVReg[Val];
   // Check if this is the first time we see Val.
-  if (ValRegSequence.empty()) {
+  if (!ValReg) {
     // Fill ValRegsSequence with the sequence of registers
     // we need to concat together to produce the value.
     assert(Val->getType()->isSized() &&
@@ -41,12 +41,10 @@ const VRegsSequence &IRTranslator::getOrCreateVRegs(const Value *Val) {
     assert(!Val->getType()->isAggregateType() && "Not yet implemented");
     unsigned Size = Val->getType()->getPrimitiveSizeInBits();
     unsigned VReg = MRI->createGenericVirtualRegister(Size);
-    ValRegSequence.push_back(VReg);
+    ValReg = VReg;
     assert(!isa<Constant>(Val) && "Not yet implemented");
   }
-  assert(ValRegSequence.size() == 1 &&
-         "We support only one vreg per value at the moment");
-  return ValRegSequence;
+  return ValReg;
 }
 
 MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock *BB) {
@@ -64,9 +62,9 @@ bool IRTranslator::translateADD(const Instruction &Inst) {
   // Unless the value is a Constant => loadimm cst?
   // or inline constant each time?
   // Creation of a virtual register needs to have a size.
-  unsigned Op0 = *getOrCreateVRegs(Inst.getOperand(0)).begin();
-  unsigned Op1 = *getOrCreateVRegs(Inst.getOperand(1)).begin();
-  unsigned Res = *getOrCreateVRegs(&Inst).begin();
+  unsigned Op0 = getOrCreateVReg(Inst.getOperand(0));
+  unsigned Op1 = getOrCreateVReg(Inst.getOperand(1));
+  unsigned Res = getOrCreateVReg(&Inst);
   MIRBuilder.buildInstr(TargetOpcode::G_ADD, Inst.getType(), Res, Op0, Op1);
   return true;
 }
@@ -78,7 +76,7 @@ bool IRTranslator::translateReturn(const Instruction &Inst) {
   // this is not important as a return is the last instruction
   // of the block anyway.
   return TLI->LowerReturn(MIRBuilder, Ret,
-                          !Ret ? 0 : *getOrCreateVRegs(Ret).begin());
+                          !Ret ? 0 : getOrCreateVReg(Ret));
 }
 
 bool IRTranslator::translate(const Instruction &Inst) {
@@ -98,7 +96,7 @@ bool IRTranslator::translate(const Instruction &Inst) {
 void IRTranslator::finalize() {
   // Release the memory used by the different maps we
   // needed during the translation.
-  ValToVRegs.clear();
+  ValToVReg.clear();
   Constants.clear();
 }
 
@@ -114,7 +112,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
   MIRBuilder.setBasicBlock(MBB);
   SmallVector<unsigned, 8> VRegArgs;
   for (const Argument &Arg: F.args())
-    VRegArgs.push_back(*getOrCreateVRegs(&Arg).begin());
+    VRegArgs.push_back(getOrCreateVReg(&Arg));
   bool Succeeded = TLI->LowerFormalArguments(MIRBuilder, F.getArgumentList(),
                                              VRegArgs);
   if (!Succeeded)