[llvm] r276799 - GlobalISel: add generic load and store instructions.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 26 13:23:27 PDT 2016
Author: tnorthover
Date: Tue Jul 26 15:23:26 2016
New Revision: 276799
URL: http://llvm.org/viewvc/llvm-project?rev=276799&view=rev
Log:
GlobalISel: add generic load and store instructions.
Pretty straightforward, the only oddity is the MachineMemOperand (which it's
surprisingly difficult to share code for).
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/TargetOpcodes.def
llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.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=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Tue Jul 26 15:23:26 2016
@@ -97,6 +97,12 @@ private:
/// emitted.
bool translateBitCast(const CastInst &CI);
+ /// Translate an LLVM load instruction into generic IR.
+ bool translateLoad(const LoadInst &LI);
+
+ /// Translate an LLVM store instruction into generic IR.
+ bool translateStore(const StoreInst &SI);
+
/// Translate one of LLVM's cast instructions into MachineInstrs, with the
/// given generic Opcode.
bool translateCast(unsigned Opcode, const CastInst &CI);
@@ -141,10 +147,16 @@ private:
/// If such VReg does not exist, it is created.
unsigned getOrCreateVReg(const Value &Val);
+ /// Get the alignment of the given memory operation instruction. This will
+ /// either be the explicitly specified value or the ABI-required alignment for
+ /// the type being accessed (according to the Module's DataLayout).
+ unsigned getMemOpAlignment(const Instruction &I);
+
/// Get the MachineBasicBlock that represents \p BB.
/// If such basic block does not exist, it is created.
MachineBasicBlock &getOrCreateBB(const BasicBlock &BB);
+
public:
// Ctor, nothing fancy.
IRTranslator();
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=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Tue Jul 26 15:23:26 2016
@@ -192,6 +192,28 @@ public:
/// \return The newly created instruction.
MachineInstr *buildCopy(unsigned Res, unsigned Op);
+ /// Build and insert `Res<def> = G_LOAD { VTy, PTy } Addr, MMO`.
+ ///
+ /// Loads the value of (sized) type \p VTy stored at \p Addr (in address space
+ /// given by \p PTy). Puts the result in Res.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildLoad(LLT VTy, LLT PTy, unsigned Res, unsigned Addr,
+ MachineMemOperand &MMO);
+
+ /// Build and insert `G_STORE { VTy, PTy } Val, Addr, MMO`.
+ ///
+ /// Stores the value \p Val of (sized) \p VTy to \p Addr (in address space
+ /// given by \p PTy).
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildStore(LLT VTy, LLT PTy, unsigned Val, unsigned Addr,
+ MachineMemOperand &MMO);
+
/// Build and insert `Res0<def>, ... = G_EXTRACT Ty Src, Idx0, ...`.
///
/// If \p Ty has size N bits, G_EXTRACT sets \p Res[0] to bits `[Idxs[0],
Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Tue Jul 26 15:23:26 2016
@@ -40,10 +40,10 @@ def G_BITCAST : Instruction {
let hasSideEffects = 0;
}
-
//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
+
// Generic addition.
def G_ADD : Instruction {
let OutOperandList = (outs unknown:$dst);
@@ -77,6 +77,26 @@ def G_OR : Instruction {
}
//------------------------------------------------------------------------------
+// Memory ops
+//------------------------------------------------------------------------------
+
+// Generic load. Expects a MachineMemOperand in addition to explicit operands.
+def G_LOAD : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$addr);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+}
+
+// Generic store. Expects a MachineMemOperand in addition to explicit operands.
+def G_STORE : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins unknown:$src, unknown:$addr);
+ let hasSideEffects = 0;
+ let mayStore = 1;
+}
+
+//------------------------------------------------------------------------------
// Variadic ops
//------------------------------------------------------------------------------
Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Tue Jul 26 15:23:26 2016
@@ -190,6 +190,12 @@ HANDLE_TARGET_OPCODE(G_INTTOPTR)
/// COPY is the relevant instruction.
HANDLE_TARGET_OPCODE(G_BITCAST)
+/// Generic load.
+HANDLE_TARGET_OPCODE(G_LOAD)
+
+/// Generic store.
+HANDLE_TARGET_OPCODE(G_STORE)
+
/// 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=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Tue Jul 26 15:23:26 2016
@@ -52,6 +52,21 @@ unsigned IRTranslator::getOrCreateVReg(c
return ValReg;
}
+unsigned IRTranslator::getMemOpAlignment(const Instruction &I) {
+ unsigned Alignment = 0;
+ Type *ValTy = nullptr;
+ if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
+ Alignment = SI->getAlignment();
+ ValTy = SI->getValueOperand()->getType();
+ } else if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+ Alignment = LI->getAlignment();
+ ValTy = LI->getType();
+ } else
+ llvm_unreachable("unhandled memory instruction");
+
+ return Alignment ? Alignment : DL->getABITypeAlignment(ValTy);
+}
+
MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock &BB) {
MachineBasicBlock *&MBB = BBToMBB[&BB];
if (!MBB) {
@@ -100,6 +115,39 @@ bool IRTranslator::translateBr(const Ins
return true;
}
+bool IRTranslator::translateLoad(const LoadInst &LI) {
+ assert(LI.isSimple() && "only simple loads are supported at the moment");
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ unsigned Res = getOrCreateVReg(LI);
+ unsigned Addr = getOrCreateVReg(*LI.getPointerOperand());
+ LLT VTy{*LI.getType()}, PTy{*LI.getPointerOperand()->getType()};
+
+ MIRBuilder.buildLoad(
+ VTy, PTy, Res, Addr,
+ *MF.getMachineMemOperand(MachinePointerInfo(LI.getPointerOperand()),
+ MachineMemOperand::MOLoad,
+ VTy.getSizeInBits() / 8, getMemOpAlignment(LI)));
+ return true;
+}
+
+bool IRTranslator::translateStore(const StoreInst &SI) {
+ assert(SI.isSimple() && "only simple loads are supported at the moment");
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ unsigned Val = getOrCreateVReg(*SI.getValueOperand());
+ unsigned Addr = getOrCreateVReg(*SI.getPointerOperand());
+ LLT VTy{*SI.getValueOperand()->getType()},
+ PTy{*SI.getPointerOperand()->getType()};
+
+ MIRBuilder.buildStore(
+ VTy, PTy, Val, Addr,
+ *MF.getMachineMemOperand(MachinePointerInfo(SI.getPointerOperand()),
+ MachineMemOperand::MOStore,
+ VTy.getSizeInBits() / 8, getMemOpAlignment(SI)));
+ return true;
+}
+
bool IRTranslator::translateBitCast(const CastInst &CI) {
if (LLT{*CI.getDestTy()} == LLT{*CI.getSrcTy()}) {
MIRBuilder.buildCopy(getOrCreateVReg(CI),
@@ -163,6 +211,12 @@ bool IRTranslator::translate(const Instr
case Instruction::PtrToInt:
return translateCast(TargetOpcode::G_PTRTOINT, cast<CastInst>(Inst));
+ // Memory ops.
+ case Instruction::Load:
+ return translateLoad(cast<LoadInst>(Inst));
+ case Instruction::Store:
+ return translateStore(cast<StoreInst>(Inst));
+
case Instruction::Alloca:
return translateStaticAlloca(cast<AllocaInst>(Inst));
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Tue Jul 26 15:23:26 2016
@@ -94,6 +94,23 @@ MachineInstr *MachineIRBuilder::buildCop
return buildInstr(TargetOpcode::COPY, Res, Op);
}
+MachineInstr *MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
+ unsigned Addr,
+ MachineMemOperand &MMO) {
+ MachineInstr *NewMI = buildInstr(TargetOpcode::G_LOAD, {VTy, PTy}, Res, Addr);
+ NewMI->addMemOperand(getMF(), &MMO);
+ return NewMI;
+}
+
+MachineInstr *MachineIRBuilder::buildStore(LLT VTy, LLT PTy, unsigned Val,
+ unsigned Addr,
+ MachineMemOperand &MMO) {
+ MachineInstr *NewMI = buildInstr(TargetOpcode::G_STORE, {VTy, PTy});
+ NewMI->addMemOperand(getMF(), &MMO);
+ MachineInstrBuilder(getMF(), NewMI).addReg(Val).addReg(Addr);
+ return NewMI;
+}
+
MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
unsigned Src,
ArrayRef<unsigned> Indexes) {
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=276799&r1=276798&r2=276799&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Tue Jul 26 15:23:26 2016
@@ -165,3 +165,33 @@ define i64 @bitcast(i64 %a) {
%res2 = bitcast <2 x i32> %res1 to i64
ret i64 %res2
}
+
+; CHECK-LABEL: name: load
+; CHECK: [[ADDR:%[0-9]+]](64) = COPY %x0
+; CHECK: [[ADDR42:%[0-9]+]](64) = COPY %x1
+; CHECK: [[VAL1:%[0-9]+]](64) = G_LOAD { s64, p0 } [[ADDR]] :: (load 8 from %ir.addr, align 16)
+; CHECK: [[VAL2:%[0-9]+]](64) = G_LOAD { s64, p42 } [[ADDR42]] :: (load 8 from %ir.addr42)
+; CHECK: [[SUM:%.*]](64) = G_ADD s64 [[VAL1]], [[VAL2]]
+; CHECK: %x0 = COPY [[SUM]]
+; CHECK: RET_ReallyLR implicit %x0
+define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
+ %val1 = load i64, i64* %addr, align 16
+ %val2 = load i64, i64 addrspace(42)* %addr42
+ %sum = add i64 %val1, %val2
+ ret i64 %sum
+}
+
+; CHECK-LABEL: name: store
+; CHECK: [[ADDR:%[0-9]+]](64) = COPY %x0
+; CHECK: [[ADDR42:%[0-9]+]](64) = COPY %x1
+; CHECK: [[VAL1:%[0-9]+]](64) = COPY %x2
+; CHECK: [[VAL2:%[0-9]+]](64) = COPY %x3
+; CHECK: G_STORE { s64, p0 } [[VAL1]], [[ADDR]] :: (store 8 into %ir.addr, align 16)
+; CHECK: G_STORE { s64, p42 } [[VAL2]], [[ADDR42]] :: (store 8 into %ir.addr42)
+; CHECK: RET_ReallyLR
+define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
+ store i64 %val1, i64* %addr, align 16
+ store i64 %val2, i64 addrspace(42)* %addr42
+ %sum = add i64 %val1, %val2
+ ret void
+}
More information about the llvm-commits
mailing list