forked from OSchip/llvm-project
[GlobalISel] Add a G_BLOCK_ADDR opcode to handle IR blockaddress constants.
Differential Revision: https://reviews.llvm.org/D49900 llvm-svn: 338335
This commit is contained in:
parent
cae1b9fef2
commit
6aff5a7810
|
@ -942,6 +942,16 @@ public:
|
||||||
/// \return a MachineInstrBuilder for the newly created instruction.
|
/// \return a MachineInstrBuilder for the newly created instruction.
|
||||||
MachineInstrBuilder buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr,
|
MachineInstrBuilder buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr,
|
||||||
unsigned Val, MachineMemOperand &MMO);
|
unsigned Val, MachineMemOperand &MMO);
|
||||||
|
|
||||||
|
/// Build and insert \p Res = G_BLOCK_ADDR \p BA
|
||||||
|
///
|
||||||
|
/// G_BLOCK_ADDR computes the address of a basic block.
|
||||||
|
///
|
||||||
|
/// \pre setBasicBlock or setMI must have been called.
|
||||||
|
/// \pre \p Res must be a generic virtual register of a pointer type.
|
||||||
|
///
|
||||||
|
/// \return The newly created instruction.
|
||||||
|
MachineInstrBuilder buildBlockAddress(unsigned Res, const BlockAddress *BA);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A CRTP class that contains methods for building instructions that can
|
/// A CRTP class that contains methods for building instructions that can
|
||||||
|
|
|
@ -470,12 +470,15 @@ HANDLE_TARGET_OPCODE(G_BSWAP)
|
||||||
/// Generic AddressSpaceCast.
|
/// Generic AddressSpaceCast.
|
||||||
HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST)
|
HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST)
|
||||||
|
|
||||||
|
/// Generic block address
|
||||||
|
HANDLE_TARGET_OPCODE(G_BLOCK_ADDR)
|
||||||
|
|
||||||
// TODO: Add more generic opcodes as we move along.
|
// TODO: Add more generic opcodes as we move along.
|
||||||
|
|
||||||
/// Marker for the end of the generic opcode.
|
/// Marker for the end of the generic opcode.
|
||||||
/// This is used to check if an opcode is in the range of the
|
/// This is used to check if an opcode is in the range of the
|
||||||
/// generic opcodes.
|
/// generic opcodes.
|
||||||
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_ADDRSPACE_CAST)
|
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BLOCK_ADDR)
|
||||||
|
|
||||||
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||||
/// The target-specific post-isel opcode values start here.
|
/// The target-specific post-isel opcode values start here.
|
||||||
|
|
|
@ -131,6 +131,13 @@ def G_ADDRSPACE_CAST : GenericInstruction {
|
||||||
let InOperandList = (ins type1:$src);
|
let InOperandList = (ins type1:$src);
|
||||||
let hasSideEffects = 0;
|
let hasSideEffects = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def G_BLOCK_ADDR : GenericInstruction {
|
||||||
|
let OutOperandList = (outs type0:$dst);
|
||||||
|
let InOperandList = (ins unknown:$ba);
|
||||||
|
let hasSideEffects = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Binary ops.
|
// Binary ops.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1503,6 +1503,8 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
|
||||||
Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
|
Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
|
||||||
}
|
}
|
||||||
EntryBuilder.buildMerge(Reg, Ops);
|
EntryBuilder.buildMerge(Reg, Ops);
|
||||||
|
} else if (auto *BA = dyn_cast<BlockAddress>(&C)) {
|
||||||
|
EntryBuilder.buildBlockAddress(Reg, BA);
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -809,6 +809,15 @@ MachineIRBuilderBase::buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr,
|
||||||
MMO);
|
MMO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MachineInstrBuilder
|
||||||
|
MachineIRBuilderBase::buildBlockAddress(unsigned Res, const BlockAddress *BA) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert(getMRI()->getType(Res).isPointer() && "invalid res type");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA);
|
||||||
|
}
|
||||||
|
|
||||||
void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src,
|
void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src,
|
||||||
bool IsExtend) {
|
bool IsExtend) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
@ -2147,3 +2147,15 @@ define i32 @test_atomicrmw_umax(i256* %addr) {
|
||||||
%oldval.trunc = trunc i256 %oldval to i32
|
%oldval.trunc = trunc i256 %oldval to i32
|
||||||
ret i32 %oldval.trunc
|
ret i32 %oldval.trunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test_blockaddress() {
|
||||||
|
; CHECK-LABEL: name: test_blockaddress
|
||||||
|
; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||||
|
; CHECK: G_STORE [[BADDR]](p0)
|
||||||
|
store i8* blockaddress(@test_blockaddress, %block), i8** @addr
|
||||||
|
indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block]
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue