summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-09-12 12:10:41 +0000
committerTim Northover <tnorthover@apple.com>2016-09-12 12:10:41 +0000
commit032548fc5eb206176b68e13cde39df682377b0fc (patch)
tree0d8fbb0429f8997d3869683f8d020981a9cd33b2
parent03ea468a1ccc39a1a451a12b1ce48d43678aa927 (diff)
downloadbcm5719-llvm-032548fc5eb206176b68e13cde39df682377b0fc.tar.gz
bcm5719-llvm-032548fc5eb206176b68e13cde39df682377b0fc.zip
GlobalISel: support translation of global addresses.
llvm-svn: 281207
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h12
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td6
-rw-r--r--llvm/include/llvm/Target/TargetOpcodes.def3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp2
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp12
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll28
6 files changed, 63 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 2dba3de1462..3c9a7c2a938 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -122,6 +122,18 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx);
+ /// Build and insert \p Res<def> = G_GLOBAL_VALUE \p GV
+ ///
+ /// G_GLOBAL_VALUE materializes the address of the specified global
+ /// into \p Res.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res must be a generic virtual register with pointer type
+ /// in the same address space as \p GV.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildGlobalValue(unsigned Res, const GlobalValue *GV);
+
/// Build and insert \p Res<def> = G_ADD \p Op0, \p Op1
///
/// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 2372a5382a4..8694eb5797d 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -55,6 +55,12 @@ def G_FRAME_INDEX : Instruction {
let hasSideEffects = 0;
}
+def G_GLOBAL_VALUE : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins unknown:$src);
+ let hasSideEffects = 0;
+}
+
def G_INTTOPTR : Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def
index a3c1258ea02..f1a956e56fe 100644
--- a/llvm/include/llvm/Target/TargetOpcodes.def
+++ b/llvm/include/llvm/Target/TargetOpcodes.def
@@ -200,6 +200,9 @@ HANDLE_TARGET_OPCODE(G_XOR)
/// stack-based object.
HANDLE_TARGET_OPCODE(G_FRAME_INDEX)
+/// Generic reference to global value.
+HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)
+
/// Generic instruction to extract blocks of bits from the register given
/// (typically a sub-register COPY after instruction selection).
HANDLE_TARGET_OPCODE(G_EXTRACT)
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index c891502112f..40c46d61041 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -508,6 +508,8 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
EntryBuilder.buildInstr(TargetOpcode::G_CONSTANT)
.addDef(Reg)
.addImm(0);
+ else if (auto GV = dyn_cast<GlobalValue>(&C))
+ EntryBuilder.buildGlobalValue(Reg, GV);
else if (auto CE = dyn_cast<ConstantExpr>(&C)) {
switch(CE->getOpcode()) {
#define HANDLE_INST(NUM, OPCODE, CLASS) \
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index acf94495df7..7aa5405ef20 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -84,6 +84,18 @@ MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
.addFrameIndex(Idx);
}
+MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
+ const GlobalValue *GV) {
+ assert(MRI->getType(Res).isPointer() && "invalid operand type");
+ assert(MRI->getType(Res).getAddressSpace() ==
+ GV->getType()->getAddressSpace() &&
+ "address space mismatch");
+
+ return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
+ .addDef(Res)
+ .addGlobalAddress(GV);
+}
+
MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
unsigned Op1) {
assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
index fea1f5370ef..723dcba9b48 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -827,3 +827,31 @@ define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
store i1 %res, i1* %bool.addr
ret void
}
+
+@var = global i32 0
+
+define i32* @test_global() {
+; CHECK-LABEL: name: test_global
+; CHECK: [[TMP:%[0-9]+]](p0) = G_GLOBAL_VALUE @var{{$}}
+; CHECK: %x0 = COPY [[TMP]](p0)
+
+ ret i32* @var
+}
+
+@var1 = addrspace(42) global i32 0
+define i32 addrspace(42)* @test_global_addrspace() {
+; CHECK-LABEL: name: test_global
+; CHECK: [[TMP:%[0-9]+]](p42) = G_GLOBAL_VALUE @var1{{$}}
+; CHECK: %x0 = COPY [[TMP]](p42)
+
+ ret i32 addrspace(42)* @var1
+}
+
+
+define void()* @test_global_func() {
+; CHECK-LABEL: name: test_global_func
+; CHECK: [[TMP:%[0-9]+]](p0) = G_GLOBAL_VALUE @allocai64{{$}}
+; CHECK: %x0 = COPY [[TMP]](p0)
+
+ ret void()* @allocai64
+}
OpenPOWER on IntegriCloud