[llvm] r277835 - GlobalISel: IRTranslate PHI instructions

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 5 10:16:41 PDT 2016


Author: tnorthover
Date: Fri Aug  5 12:16:40 2016
New Revision: 277835

URL: http://llvm.org/viewvc/llvm-project?rev=277835&view=rev
Log:
GlobalISel: IRTranslate PHI instructions

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h?rev=277835&r1=277834&r2=277835&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Fri Aug  5 12:16:40 2016
@@ -64,8 +64,15 @@ private:
   // do not appear in that map.
   SmallSetVector<const Constant *, 8> Constants;
 
+  // N.b. it's not completely obvious that this will be sufficient for every
+  // LLVM IR construct (with "invoke" being the obvious candidate to mess up our
+  // lives.
   DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB;
 
+  // List of stubbed PHI instructions, for values and basic blocks to be filled
+  // in once all MachineBasicBlocks have been created.
+  SmallVector<std::pair<const PHINode *, MachineInstr *>, 4> PendingPHIs;
+
   /// Methods for translating form LLVM IR to MachineInstr.
   /// \see ::translate for general information on the translate methods.
   /// @{
@@ -111,10 +118,17 @@ private:
   /// given generic Opcode.
   bool translateCast(unsigned Opcode, const CastInst &CI);
 
-  /// Translate alloca instruction (i.e. one of constant size and in the first
-  /// basic block).
+  /// Translate static alloca instruction (i.e. one  of constant size and in the
+  /// first basic block).
   bool translateStaticAlloca(const AllocaInst &Inst);
 
+  /// Translate a phi instruction.
+  bool translatePhi(const PHINode &PI);
+
+  /// Add remaining operands onto phis we've translated. Executed after all
+  /// MachineBasicBlocks for the function have been created.
+  void finishPendingPhis();
+
   /// Translate \p Inst into a binary operation \p Opcode.
   /// \pre \p Inst is a binary operation.
   bool translateBinaryOp(unsigned Opcode, const BinaryOperator &Inst);

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=277835&r1=277834&r2=277835&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Fri Aug  5 12:16:40 2016
@@ -225,6 +225,32 @@ bool IRTranslator::translateStaticAlloca
   return true;
 }
 
+bool IRTranslator::translatePhi(const PHINode &PI) {
+  MachineInstrBuilder MIB = MIRBuilder.buildInstr(TargetOpcode::PHI);
+  MIB.addDef(getOrCreateVReg(PI));
+
+  PendingPHIs.emplace_back(&PI, MIB.getInstr());
+  return true;
+}
+
+void IRTranslator::finishPendingPhis() {
+  for (std::pair<const PHINode *, MachineInstr *> &Phi : PendingPHIs) {
+    const PHINode *PI = Phi.first;
+    MachineInstrBuilder MIB(MIRBuilder.getMF(), Phi.second);
+
+    // All MachineBasicBlocks exist, add them to the PHI. We assume IRTranslator
+    // won't create extra control flow here, otherwise we need to find the
+    // dominating predecessor here (or perhaps force the weirder IRTranslators
+    // to provide a simple boundary).
+    for (unsigned i = 0; i < PI->getNumIncomingValues(); ++i) {
+      assert(BBToMBB[PI->getIncomingBlock(i)]->isSuccessor(MIB->getParent()) &&
+             "I appear to have misunderstood Machine PHIs");
+      MIB.addUse(getOrCreateVReg(*PI->getIncomingValue(i)));
+      MIB.addMBB(BBToMBB[PI->getIncomingBlock(i)]);
+    }
+  }
+}
+
 bool IRTranslator::translate(const Instruction &Inst) {
   MIRBuilder.setDebugLoc(Inst.getDebugLoc());
   switch(Inst.getOpcode()) {
@@ -273,6 +299,9 @@ bool IRTranslator::translate(const Instr
   case Instruction::Alloca:
     return translateStaticAlloca(cast<AllocaInst>(Inst));
 
+  case Instruction::PHI:
+    return translatePhi(cast<PHINode>(Inst));
+
   case Instruction::Unreachable:
     return true;
 
@@ -323,6 +352,8 @@ bool IRTranslator::runOnMachineFunction(
     }
   }
 
+  finishPendingPhis();
+
   // Now that the MachineFrameInfo has been configured, no further changes to
   // the reserved registers are possible.
   MRI->freezeReservedRegs(MF);

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=277835&r1=277834&r2=277835&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Fri Aug  5 12:16:40 2016
@@ -95,6 +95,8 @@ bool AArch64CallLowering::lowerFormalArg
       // We don't care about bitcast.
       break;
     case CCValAssign::AExt:
+      // Existing high bits are fine for anyext (whatever they are).
+      break;
     case CCValAssign::SExt:
     case CCValAssign::ZExt:
       // Zero/Sign extend the register.

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll?rev=277835&r1=277834&r2=277835&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Fri Aug  5 12:16:40 2016
@@ -305,3 +305,32 @@ define void @unreachable(i32 %a) {
   %sum = add i32 %a, %a
   unreachable
 }
+
+; CHECK-LABEL: name: test_phi
+; CHECK:     G_BRCOND s1 {{%.*}}, %[[TRUE:bb\.[0-9]+]]
+; CHECK:     G_BR unsized %[[FALSE:bb\.[0-9]+]]
+
+; CHECK: [[TRUE]]:
+; CHECK:     [[RES1:%[0-9]+]](32) = G_LOAD { s32, p0 }
+
+; CHECK: [[FALSE]]:
+; CHECK:     [[RES2:%[0-9]+]](32) = G_LOAD { s32, p0 }
+
+; CHECK:     [[RES:%[0-9]+]](32) = PHI [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]]
+; CHECK:     %w0 = COPY [[RES]]
+
+define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
+  br i1 %tst, label %true, label %false
+
+true:
+  %res1 = load i32, i32* %addr1
+  br label %end
+
+false:
+  %res2 = load i32, i32* %addr2
+  br label %end
+
+end:
+  %res = phi i32 [%res1, %true], [%res2, %false]
+  ret i32 %res
+}




More information about the llvm-commits mailing list