GlobalISel: support translation of global addresses.

llvm-svn: 281207
This commit is contained in:
Tim Northover 2016-09-12 12:10:41 +00:00
parent 03ea468a1c
commit 032548fc5e
6 changed files with 63 additions and 0 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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) \

View File

@ -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()) &&

View File

@ -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
}