From 8d8812c5d7e546b40e0549fd3d82f74c7f6d4ba5 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 1 Sep 2016 20:45:41 +0000 Subject: [PATCH] GlobalISel: add a G_PHI instruction to give phis a type. They're another source of generic vregs, which are going to need a type on the definition when we remove the register width from MachineRegisterInfo. llvm-svn: 280412 --- llvm/include/llvm/CodeGen/MachineInstr.h | 5 ++++- llvm/include/llvm/Target/GenericOpcodes.td | 7 +++++++ llvm/include/llvm/Target/TargetOpcodes.def | 3 +++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 +- llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp | 4 +++- llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 6 ++++++ llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll | 2 +- 7 files changed, 25 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 264a91b..49fd21e 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -793,7 +793,10 @@ public: && getOperand(1).isImm(); } - bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } + bool isPHI() const { + return getOpcode() == TargetOpcode::PHI || + getOpcode() == TargetOpcode::G_PHI; + } bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 0b304dd..0481006 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -415,6 +415,13 @@ def G_INTRINSIC_W_SIDE_EFFECTS : Instruction { let mayStore = 1; } +// PHI node bearing an LLT. +def G_PHI : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins variable_ops); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Branches. //------------------------------------------------------------------------------ diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index 48d6c74..cc54d6c 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/include/llvm/Target/TargetOpcodes.def @@ -336,6 +336,9 @@ HANDLE_TARGET_OPCODE(G_UITOFP) /// Generic type specifier for untyped registers. HANDLE_TARGET_OPCODE(G_TYPE) +/// Generic PHI node (so that the type of the vreg can be set). +HANDLE_TARGET_OPCODE(G_PHI) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index a27d539..f0ac167 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -405,7 +405,7 @@ bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) { bool IRTranslator::translatePHI(const User &U) { const PHINode &PI = cast(U); - MachineInstrBuilder MIB = MIRBuilder.buildInstr(TargetOpcode::PHI); + auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, LLT{*U.getType()}); MIB.addDef(getOrCreateVReg(PI)); PendingPHIs.emplace_back(&PI, MIB.getInstr()); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp index cc3d4ec..5a15f65 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp @@ -30,8 +30,10 @@ MachineLegalizer::MachineLegalizer() : TablesInitialized(false) { DefaultActions[TargetOpcode::G_ANYEXT] = Legal; DefaultActions[TargetOpcode::G_TRUNC] = Legal; - // G_TYPE is essentially an annotated COPY so it's always legal. + // G_TYPE and G_PHI are essentially an annotated COPY/PHI instructions so + // they're always legal. DefaultActions[TargetOpcode::G_TYPE] = Legal; + DefaultActions[TargetOpcode::G_PHI] = Legal; DefaultActions[TargetOpcode::G_INTRINSIC] = Legal; DefaultActions[TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS] = Legal; diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 779b624..26342a1 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -235,6 +235,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return true; } + case TargetOpcode::G_PHI: { + I.setDesc(TII.get(TargetOpcode::PHI)); + I.removeTypes(); + return true; + } + case TargetOpcode::G_FRAME_INDEX: { // allocas and G_FRAME_INDEX are only supported in addrspace(0). if (I.getType() != LLT::pointer(0)) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 0e79eed..c95fb59 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -325,7 +325,7 @@ define void @intrinsics(i32 %cur, i32 %bits) { ; CHECK: [[FALSE]]: ; CHECK: [[RES2:%[0-9]+]](32) = G_LOAD { s32, p0 } -; CHECK: [[RES:%[0-9]+]](32) = PHI [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]] +; CHECK: [[RES:%[0-9]+]](32) = G_PHI s32 [[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 -- 2.7.4