forked from OSchip/llvm-project
GlobalISel: IRTranslate PHI instructions
llvm-svn: 277835
This commit is contained in:
parent
1313ae306a
commit
97d0cb3165
|
@ -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);
|
||||
|
|
|
@ -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<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 Instruction &Inst) {
|
|||
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(MachineFunction &MF) {
|
|||
}
|
||||
}
|
||||
|
||||
finishPendingPhis();
|
||||
|
||||
// Now that the MachineFrameInfo has been configured, no further changes to
|
||||
// the reserved registers are possible.
|
||||
MRI->freezeReservedRegs(MF);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue