From: Tim Northover Date: Fri, 5 Aug 2016 17:16:40 +0000 (+0000) Subject: GlobalISel: IRTranslate PHI instructions X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=97d0cb316526fd1a6fb0f4e0bfaa0218b920810f;p=platform%2Fupstream%2Fllvm.git GlobalISel: IRTranslate PHI instructions llvm-svn: 277835 --- diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index f267d6c..f6c147d 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -64,8 +64,15 @@ private: // do not appear in that map. SmallSetVector 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 BBToMBB; + // List of stubbed PHI instructions, for values and basic blocks to be filled + // in once all MachineBasicBlocks have been created. + SmallVector, 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); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index cce4149..2982731 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -225,6 +225,32 @@ bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) { 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 &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 Instruction &Inst) { case Instruction::Alloca: return translateStaticAlloca(cast(Inst)); + case Instruction::PHI: + return translatePhi(cast(Inst)); + case Instruction::Unreachable: return true; @@ -323,6 +352,8 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) { } } + finishPendingPhis(); + // Now that the MachineFrameInfo has been configured, no further changes to // the reserved registers are possible. MRI->freezeReservedRegs(MF); diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index 7718b5b..9abac46 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -95,6 +95,8 @@ bool AArch64CallLowering::lowerFormalArguments( // 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. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index c356bae..30fce4d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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 +}