[llvm] r277224 - GlobalISel: support translation of intrinsic calls.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 29 15:32:36 PDT 2016
Author: tnorthover
Date: Fri Jul 29 17:32:36 2016
New Revision: 277224
URL: http://llvm.org/viewvc/llvm-project?rev=277224&view=rev
Log:
GlobalISel: support translation of intrinsic calls.
These come in two variants for now: G_INTRINSIC and G_INTRINSIC_W_SIDE_EFFECTS.
We may decide to split the latter up with finer-grained restrictions later, if
necessary.
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
llvm/trunk/include/llvm/Target/GenericOpcodes.td
llvm/trunk/include/llvm/Target/TargetIntrinsicInfo.h
llvm/trunk/include/llvm/Target/TargetOpcodes.def
llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
llvm/trunk/lib/Target/TargetIntrinsicInfo.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=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Fri Jul 29 17:32:36 2016
@@ -103,6 +103,10 @@ private:
/// Translate an LLVM store instruction into generic IR.
bool translateStore(const StoreInst &SI);
+ /// Translate call instruction.
+ /// \pre \p Inst is a branch instruction.
+ bool translateCall(const CallInst &Inst);
+
/// Translate one of LLVM's cast instructions into MachineInstrs, with the
/// given generic Opcode.
bool translateCast(unsigned Opcode, const CastInst &CI);
@@ -119,6 +123,7 @@ private:
/// \pre \p Inst is a branch instruction.
bool translateBr(const BranchInst &Inst);
+
/// Translate return (ret) instruction.
/// The target needs to implement CallLowering::lowerReturn for
/// this to succeed.
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Fri Jul 29 17:32:36 2016
@@ -204,6 +204,19 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildSequence(LLT Ty, unsigned Res,
ArrayRef<unsigned> Ops);
+
+ /// Build and insert either a G_INTRINSIC (if \p HasSideEffects is false) or
+ /// G_INTRINSIC_W_SIDE_EFFECTS instruction. Its first operand will be the
+ /// result register definition unless \p Reg is NoReg (== 0). The second
+ /// operand will be the intrinsic's ID.
+ ///
+ /// Callers are expected to add the required definitions and uses afterwards.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildIntrinsic(ArrayRef<LLT> Tys, Intrinsic::ID ID,
+ unsigned Res, bool HasSideEffects);
};
} // End namespace llvm.
Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Fri Jul 29 17:32:36 2016
@@ -125,6 +125,22 @@ def G_SEQUENCE : Instruction {
let hasSideEffects = 0;
}
+// Intrinsic without side effects.
+def G_INTRINSIC : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins unknown:$intrin, variable_ops);
+ let hasSideEffects = 0;
+}
+
+// Intrinsic with side effects.
+def G_INTRINSIC_W_SIDE_EFFECTS : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins unknown:$intrin, variable_ops);
+ let hasSideEffects = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
//------------------------------------------------------------------------------
// Branches.
//------------------------------------------------------------------------------
Modified: llvm/trunk/include/llvm/Target/TargetIntrinsicInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetIntrinsicInfo.h?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetIntrinsicInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetIntrinsicInfo.h Fri Jul 29 17:32:36 2016
@@ -53,7 +53,7 @@ public:
}
/// Return the target intrinsic ID of a function, or 0.
- virtual unsigned getIntrinsicID(Function *F) const;
+ virtual unsigned getIntrinsicID(const Function *F) const;
/// Returns true if the intrinsic can be overloaded.
virtual bool isOverloaded(unsigned IID) const = 0;
Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Fri Jul 29 17:32:36 2016
@@ -202,6 +202,12 @@ HANDLE_TARGET_OPCODE(G_STORE)
/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)
+/// Generic intrinsic use (without side effects).
+HANDLE_TARGET_OPCODE(G_INTRINSIC)
+
+/// Generic intrinsic use (with side effects).
+HANDLE_TARGET_OPCODE(G_INTRINSIC_W_SIDE_EFFECTS)
+
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Fri Jul 29 17:32:36 2016
@@ -19,8 +19,10 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
+#include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetLowering.h"
#define DEBUG_TYPE "irtranslator"
@@ -175,6 +177,34 @@ bool IRTranslator::translateCast(unsigne
return true;
}
+bool IRTranslator::translateCall(const CallInst &CI) {
+ auto TII = MIRBuilder.getMF().getTarget().getIntrinsicInfo();
+ const Function &F = *CI.getCalledFunction();
+ Intrinsic::ID ID = F.getIntrinsicID();
+ if (TII && ID == Intrinsic::not_intrinsic)
+ ID = static_cast<Intrinsic::ID>(TII->getIntrinsicID(&F));
+
+ assert(ID != Intrinsic::not_intrinsic && "FIXME: support real calls");
+
+ // Need types (starting with return) & args.
+ SmallVector<LLT, 4> Tys;
+ Tys.emplace_back(*CI.getType());
+ for (auto &Arg : CI.arg_operands())
+ Tys.emplace_back(*Arg->getType());
+
+ unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI);
+ MachineInstrBuilder MIB =
+ MIRBuilder.buildIntrinsic(Tys, ID, Res, !CI.doesNotAccessMemory());
+
+ for (auto &Arg : CI.arg_operands()) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg))
+ MIB.addImm(CI->getSExtValue());
+ else
+ MIB.addUse(getOrCreateVReg(*Arg));
+ }
+ return true;
+}
+
bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) {
assert(AI.isStaticAlloca() && "only handle static allocas now");
MachineFunction &MF = MIRBuilder.getMF();
@@ -218,6 +248,10 @@ bool IRTranslator::translate(const Instr
case Instruction::Ret:
return translateReturn(cast<ReturnInst>(Inst));
+ // Calls
+ case Instruction::Call:
+ return translateCall(cast<CallInst>(Inst));
+
// Casts
case Instruction::BitCast:
return translateBitCast(cast<CastInst>(Inst));
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Fri Jul 29 17:32:36 2016
@@ -143,3 +143,17 @@ MachineInstrBuilder MachineIRBuilder::bu
MIB.addUse(Op);
return MIB;
}
+
+MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys,
+ Intrinsic::ID ID,
+ unsigned Res,
+ bool HasSideEffects) {
+ auto MIB =
+ buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
+ : TargetOpcode::G_INTRINSIC,
+ Tys);
+ if (Res)
+ MIB.addDef(Res);
+ MIB.addIntrinsicID(ID);
+ return MIB;
+}
Modified: llvm/trunk/lib/Target/TargetIntrinsicInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetIntrinsicInfo.cpp?rev=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetIntrinsicInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetIntrinsicInfo.cpp Fri Jul 29 17:32:36 2016
@@ -22,7 +22,7 @@ TargetIntrinsicInfo::TargetIntrinsicInfo
TargetIntrinsicInfo::~TargetIntrinsicInfo() {
}
-unsigned TargetIntrinsicInfo::getIntrinsicID(Function *F) const {
+unsigned TargetIntrinsicInfo::getIntrinsicID(const Function *F) const {
const ValueName *ValName = F->getValueName();
if (!ValName)
return 0;
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=277224&r1=277223&r2=277224&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Fri Jul 29 17:32:36 2016
@@ -252,3 +252,22 @@ define void @store(i64* %addr, i64 addrs
%sum = add i64 %val1, %val2
ret void
}
+
+; CHECK-LABEL: name: intrinsics
+; CHECK: [[CUR:%[0-9]+]](32) = COPY %w0
+; CHECK: [[BITS:%[0-9]+]](32) = COPY %w1
+; CHECK: [[PTR:%[0-9]+]](64) = G_INTRINSIC { p0, s32 } intrinsic(@llvm.returnaddress), 0
+; CHECK: [[PTR_VEC:%[0-9]+]](64) = G_FRAME_INDEX p0 %stack.0.ptr.vec
+; CHECK: [[VEC:%[0-9]+]](64) = G_LOAD { <8 x s8>, p0 } [[PTR_VEC]]
+; CHECK: G_INTRINSIC_W_SIDE_EFFECTS { unsized, <8 x s8>, <8 x s8>, p0 } intrinsic(@llvm.aarch64.neon.st2), [[VEC]], [[VEC]], [[PTR]]
+; CHECK: RET_ReallyLR
+declare i8* @llvm.returnaddress(i32)
+declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
+declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*)
+define void @intrinsics(i32 %cur, i32 %bits) {
+ %ptr = call i8* @llvm.returnaddress(i32 0)
+ %ptr.vec = alloca <8 x i8>
+ %vec = load <8 x i8>, <8 x i8>* %ptr.vec
+ call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr)
+ ret void
+}
More information about the llvm-commits
mailing list