27 #define DEBUG_TYPE "legalize-mir"
32 :
MRI(MF.getRegInfo()) {
39 auto Action = LegalizerInfo.
getAction(MI, MRI);
40 switch (std::get<0>(Action)) {
46 return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
48 return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
50 return lower(MI, std::get<1>(Action), std::get<2>(Action));
77 }
while (Idx < WorkList.
size());
84 void LegalizerHelper::extractParts(
unsigned Reg,
LLT Ty,
int NumParts,
88 for (
int i = 0;
i < NumParts; ++
i) {
104 case TargetOpcode::G_FREM: {
131 case TargetOpcode::G_ADD: {
147 for (
int i = 0;
i < NumParts; ++
i) {
151 MIRBuilder.
buildUAdde(DstReg, CarryOut, Src1Regs[
i],
152 Src2Regs[i], CarryIn);
173 case TargetOpcode::G_ADD:
174 case TargetOpcode::G_AND:
175 case TargetOpcode::G_MUL:
176 case TargetOpcode::G_OR:
177 case TargetOpcode::G_XOR:
178 case TargetOpcode::G_SUB: {
197 case TargetOpcode::G_SDIV:
198 case TargetOpcode::G_UDIV: {
199 unsigned ExtOp = MI.
getOpcode() == TargetOpcode::G_SDIV
200 ? TargetOpcode::G_SEXT
201 : TargetOpcode::G_ZEXT;
221 case TargetOpcode::G_LOAD: {
224 "illegal to increase number of bytes loaded");
233 case TargetOpcode::G_STORE: {
236 "illegal to increase number of bytes modified by a store");
245 case TargetOpcode::G_CONSTANT: {
252 case TargetOpcode::G_FCONSTANT: {
259 case TargetOpcode::G_BRCOND: {
266 case TargetOpcode::G_ICMP: {
267 assert(TypeIdx == 1 &&
"unable to legalize predicate");
285 case TargetOpcode::G_GEP: {
286 assert(TypeIdx == 1 &&
"unable to legalize pointer of GEP");
297 using namespace TargetOpcode;
298 MIRBuilder.setInstr(MI);
303 case TargetOpcode::G_SREM:
304 case TargetOpcode::G_UREM: {
305 unsigned QuotReg =
MRI.createGenericVirtualRegister(Ty);
306 MIRBuilder.buildInstr(MI.
getOpcode() == G_SREM ? G_SDIV : G_UDIV)
311 unsigned ProdReg =
MRI.createGenericVirtualRegister(Ty);
330 case TargetOpcode::G_ADD: {
342 for (
int i = 0;
i < NumParts; ++
i) {
344 MIRBuilder.
buildAdd(DstReg, Src1Regs[
i], Src2Regs[i]);
void push_back(const T &Elt)
static Type * getDoubleTy(LLVMContext &C)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
LegalizeResult legalizeInstr(MachineInstr &MI, const LegalizerInfo &LegalizerInfo)
const ConstantFP * getFPImm() const
MachineBasicBlock * getMBB() const
MachineInstrBuilder buildZExt(unsigned Res, unsigned Op)
Build and insert Res<def> = G_ZEXT Op.
std::pair< LegalizeAction, LLT > getAction(const InstrAspect &Aspect) const
Determine what action should be taken to legalize the given generic instruction opcode, type-index and type.
bool isSigned() const
Determine if this instruction is using a signed comparison.
static const MCPhysReg VRegs[32]
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res<def> = G_TRUNC Op.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op)
Build and insert Res<def> = G_ANYEXT Op0.
virtual const CallLowering * getCallLowering() const
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstrBuilder buildFPTrunc(unsigned Res, unsigned Op)
Build and insert Res<def> = G_FPTRUNC Op.
LegalizerHelper(MachineFunction &MF)
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy)
Legalize an instruction by performing the operation on a wider scalar type (for example a 16-bit addi...
static Type * getFloatTy(LLVMContext &C)
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineInstrBuilder buildFConstant(unsigned Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
Reg
All possible values of the reg field in the ModR/M byte.
MachineInstrBuilder buildExtract(ArrayRef< unsigned > Results, ArrayRef< uint64_t > Indices, unsigned Src)
Build and insert `Res0<def>, ...
MachineFunction & getMF()
Getter for the function we currently build.
void recordInsertions(std::function< void(MachineInstr *)> InsertedInstr)
Control where instructions we create are recorded (typically for visiting again later during legaliza...
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned const MachineRegisterInfo * MRI
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
The instances of the Type class are immutable: once they are created, they are never changed...
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
static unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
Get the size in bits of Reg.
const MachineOperand & getOperand(unsigned i) const
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
void setMF(MachineFunction &)
Setters for the insertion point.
Some kind of error has occurred and we could not legalize this instruction.
Instruction was already legal and no change was made to the MachineFunction.
MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0, unsigned Op1, unsigned CarryIn)
Build and insert Res<def>, CarryOut<def> = G_UADDE Op0, Op1, CarryIn.
void stopRecordingInsertions()
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
The operation should be implemented as a call to some kind of runtime support library.
LegalizeResult libcall(MachineInstr &MI)
Legalize an instruction by emiting a runtime library call instead.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
virtual const TargetLowering * getTargetLowering() const
The operation should be implemented in terms of a wider scalar base-type.
unsigned getPredicate() const
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target...
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a vector instruction by splitting into multiple components, each acting on the same scalar t...
const ConstantInt * getCImm() const
The operation itself must be expressed in terms of simpler actions on this target.
static MachineOperand CreateES(const char *SymName, unsigned char TargetFlags=0)
MachineInstrBuilder buildSExt(unsigned Res, unsigned Op)
Build and insert Res<def> = G_SEXT Op.
The operation is expected to be selectable directly by the target, and no transformation is necessary...
MachineInstrBuilder buildSequence(unsigned Res, ArrayRef< unsigned > Ops, ArrayRef< uint64_t > Indices)
Build and insert Res<def> = G_SEQUENCE Op0, Idx0...
Representation of each machine instruction.
Instruction has been legalized and the MachineFunction changed.
MachineInstrBuilder buildAdd(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_ADD Op0, Op1.
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
unsigned getReg() const
getReg - Returns the register number.
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
This file describes how to lower LLVM calls to machine code calls.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res<def> = G_LOAD Addr, MMO.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
LegalizeResult legalizeInstrStep(MachineInstr &MI, const LegalizerInfo &LegalizerInfo)
Replace MI by a sequence of legal instructions that can implement the same operation.
This file describes how to lower LLVM code to machine code.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &BB)
Build and insert G_BRCOND Tst, Dest.