mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-05 02:07:16 +00:00
Revert the earlier change that removed the M_REMATERIALIZABLE machine
instruction flag, and use the flag along with a virtual member function hook for targets to override if there are instructions that are only trivially rematerializable with specific operands (i.e. constant pool loads). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9a0930dbd9
commit
d45eddd214
@ -78,6 +78,10 @@ const unsigned M_VARIABLE_OPS = 1 << 11;
|
||||
// controls execution. It may be set to 'always'.
|
||||
const unsigned M_PREDICABLE = 1 << 12;
|
||||
|
||||
// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized
|
||||
// at any time, e.g. constant generation, load from constant pool.
|
||||
const unsigned M_REMATERIALIZIBLE = 1 << 13;
|
||||
|
||||
// M_CLOBBERS_PRED - Set if this instruction may clobbers the condition code
|
||||
// register and / or registers that are used to predicate instructions.
|
||||
const unsigned M_CLOBBERS_PRED = 1 << 14;
|
||||
@ -268,6 +272,28 @@ public:
|
||||
return get(Opcode).Flags & M_NOT_DUPLICABLE;
|
||||
}
|
||||
|
||||
/// isTriviallyReMaterializable - Return true if the instruction is trivially
|
||||
/// rematerializable, meaning it has no side effects and requires no operands
|
||||
/// that aren't always available.
|
||||
bool isTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) &&
|
||||
isReallyTriviallyReMaterializable(MI);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// isReallyTriviallyReMaterializable - For instructions with opcodes for
|
||||
/// which the M_REMATERIALIZABLE flag is set, this function tests whether the
|
||||
/// instruction itself is actually trivially rematerializable, considering
|
||||
/// its operands. This is used for targets that have instructions that are
|
||||
/// only trivially rematerializable for specific uses. This predicate must
|
||||
/// return false if the instruction has any side effects other than
|
||||
/// producing a value, or if it requres any address registers that are not
|
||||
/// always available.
|
||||
virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
/// getOperandConstraint - Returns the value of the specific constraint if
|
||||
/// it is set. Returns -1 if it is not set.
|
||||
int getOperandConstraint(MachineOpCode Opcode, unsigned OpNum,
|
||||
@ -301,16 +327,6 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// isTriviallyReMaterializable - If the specified machine instruction can
|
||||
/// be trivally re-materialized at any time, e.g. constant generation or
|
||||
/// loads from constant pools. If not, return false. This predicate must
|
||||
/// return false if the instruction has any side effects other than
|
||||
/// producing the value from the load, or if it requres any address
|
||||
/// registers that are not always available.
|
||||
virtual bool isTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
|
||||
/// may be able to convert a two-address instruction into one or moretrue
|
||||
|
@ -130,20 +130,6 @@ unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) con
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case ARM::LDRcp:
|
||||
case ARM::MOVi:
|
||||
case ARM::MVNi:
|
||||
case ARM::MOVi2pieces:
|
||||
case ARM::tLDRcp:
|
||||
// These instructions are always trivially rematerializable.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned getUnindexedOpcode(unsigned Opc) {
|
||||
switch (Opc) {
|
||||
default: break;
|
||||
|
@ -87,7 +87,6 @@ public:
|
||||
unsigned &SrcReg, unsigned &DstReg) const;
|
||||
virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
|
||||
virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
|
||||
virtual bool isTriviallyReMaterializable(MachineInstr *MI) const;
|
||||
|
||||
virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
MachineBasicBlock::iterator &MBBI,
|
||||
|
@ -677,6 +677,7 @@ def LDR : AI2<(ops GPR:$dst, addrmode2:$addr),
|
||||
[(set GPR:$dst, (load addrmode2:$addr))]>;
|
||||
|
||||
// Special LDR for loads from non-pc-relative constpools.
|
||||
let isReMaterializable = 1 in
|
||||
def LDRcp : AI2<(ops GPR:$dst, addrmode2:$addr),
|
||||
"ldr", " $dst, $addr", []>;
|
||||
|
||||
@ -810,6 +811,7 @@ def MOVr : AI1<(ops GPR:$dst, GPR:$src),
|
||||
def MOVs : AI1<(ops GPR:$dst, so_reg:$src),
|
||||
"mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
|
||||
|
||||
let isReMaterializable = 1 in
|
||||
def MOVi : AI1<(ops GPR:$dst, so_imm:$src),
|
||||
"mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
|
||||
|
||||
@ -917,6 +919,7 @@ def MVNr : AI<(ops GPR:$dst, GPR:$src),
|
||||
"mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>;
|
||||
def MVNs : AI<(ops GPR:$dst, so_reg:$src),
|
||||
"mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>;
|
||||
let isReMaterializable = 1 in
|
||||
def MVNi : AI<(ops GPR:$dst, so_imm:$imm),
|
||||
"mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>;
|
||||
|
||||
@ -1187,6 +1190,7 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
// Large immediate handling.
|
||||
|
||||
// Two piece so_imms.
|
||||
let isReMaterializable = 1 in
|
||||
def MOVi2pieces : AI1x2<(ops GPR:$dst, so_imm2part:$src),
|
||||
"mov", " $dst, $src",
|
||||
[(set GPR:$dst, so_imm2part:$src)]>;
|
||||
|
@ -267,6 +267,7 @@ def tLDRpci : TIs<(ops GPR:$dst, i32imm:$addr),
|
||||
[(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
|
||||
|
||||
// Special LDR for loads from non-pc-relative constpools.
|
||||
let isReMaterializable = 1 in
|
||||
def tLDRcp : TIs<(ops GPR:$dst, i32imm:$addr),
|
||||
"ldr $dst, $addr", []>;
|
||||
} // isLoad
|
||||
|
@ -186,6 +186,7 @@ class Instruction {
|
||||
bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote?
|
||||
bit isCommutable = 0; // Is this 3 operand instruction commutable?
|
||||
bit isTerminator = 0; // Is this part of the terminator for a basic block?
|
||||
bit isReMaterializable = 0; // Is this instruction re-materializable?
|
||||
bit isPredicable = 0; // Is this instruction predicable?
|
||||
bit hasDelaySlot = 0; // Does this instruction have an delay slot?
|
||||
bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help.
|
||||
|
@ -413,10 +413,12 @@ def FSTPrr : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
|
||||
def FXCH : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
|
||||
|
||||
// Floating point constant loads.
|
||||
let isReMaterializable = 1 in {
|
||||
def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP,
|
||||
[(set RFP:$dst, fp64imm0)]>;
|
||||
def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP,
|
||||
[(set RFP:$dst, fp64imm1)]>;
|
||||
}
|
||||
|
||||
def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
|
||||
def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
|
||||
|
@ -112,20 +112,9 @@ unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI,
|
||||
}
|
||||
|
||||
|
||||
bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case X86::FpLD0:
|
||||
case X86::FpLD1:
|
||||
case X86::MOV8ri:
|
||||
case X86::MOV16ri:
|
||||
case X86::MOV32ri:
|
||||
case X86::MMX_V_SET0:
|
||||
case X86::MMX_V_SETALLONES:
|
||||
case X86::V_SET0:
|
||||
case X86::V_SETALLONES:
|
||||
// These instructions are always trivially rematerializable.
|
||||
return true;
|
||||
case X86::MOV8rm:
|
||||
case X86::MOV16rm:
|
||||
case X86::MOV16_rm:
|
||||
@ -146,7 +135,9 @@ bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
|
||||
MI->getOperand(2).getImmedValue() == 1 &&
|
||||
MI->getOperand(3).getReg() == 0;
|
||||
}
|
||||
return false;
|
||||
// All other instructions marked M_REMATERIALIZABLE are always trivially
|
||||
// rematerializable.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
|
@ -239,7 +239,7 @@ public:
|
||||
unsigned& destReg) const;
|
||||
unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
|
||||
unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
|
||||
bool isTriviallyReMaterializable(MachineInstr *MI) const;
|
||||
bool isReallyTriviallyReMaterializable(MachineInstr *MI) const;
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
|
||||
|
@ -617,6 +617,7 @@ def MOV16rr : I<0x89, MRMDestReg, (ops GR16:$dst, GR16:$src),
|
||||
"mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
|
||||
def MOV32rr : I<0x89, MRMDestReg, (ops GR32:$dst, GR32:$src),
|
||||
"mov{l} {$src, $dst|$dst, $src}", []>;
|
||||
let isReMaterializable = 1 in {
|
||||
def MOV8ri : Ii8 <0xB0, AddRegFrm, (ops GR8 :$dst, i8imm :$src),
|
||||
"mov{b} {$src, $dst|$dst, $src}",
|
||||
[(set GR8:$dst, imm:$src)]>;
|
||||
@ -626,6 +627,7 @@ def MOV16ri : Ii16<0xB8, AddRegFrm, (ops GR16:$dst, i16imm:$src),
|
||||
def MOV32ri : Ii32<0xB8, AddRegFrm, (ops GR32:$dst, i32imm:$src),
|
||||
"mov{l} {$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, imm:$src)]>;
|
||||
}
|
||||
def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
|
||||
"mov{b} {$src, $dst|$dst, $src}",
|
||||
[(store (i8 imm:$src), addr:$dst)]>;
|
||||
|
@ -503,12 +503,14 @@ def MMX_MASKMOVQ : MMXI<0xF7, MRMDestMem, (ops VR64:$src, VR64:$mask),
|
||||
|
||||
// Alias instructions that map zero vector to pxor.
|
||||
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
||||
def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (ops VR64:$dst),
|
||||
"pxor $dst, $dst",
|
||||
[(set VR64:$dst, (v1i64 immAllZerosV))]>;
|
||||
def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (ops VR64:$dst),
|
||||
"pcmpeqd $dst, $dst",
|
||||
[(set VR64:$dst, (v1i64 immAllOnesV))]>;
|
||||
let isReMaterializable = 1 in {
|
||||
def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (ops VR64:$dst),
|
||||
"pxor $dst, $dst",
|
||||
[(set VR64:$dst, (v1i64 immAllZerosV))]>;
|
||||
def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (ops VR64:$dst),
|
||||
"pcmpeqd $dst, $dst",
|
||||
[(set VR64:$dst, (v1i64 immAllOnesV))]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Non-Instruction Patterns
|
||||
|
@ -762,6 +762,7 @@ def STMXCSR : PSI<0xAE, MRM3m, (ops i32mem:$dst),
|
||||
|
||||
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
||||
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
||||
let isReMaterializable = 1 in
|
||||
def V_SET0 : PSI<0x57, MRMInitReg, (ops VR128:$dst),
|
||||
"xorps $dst, $dst",
|
||||
[(set VR128:$dst, (v4f32 immAllZerosV))]>;
|
||||
@ -1821,9 +1822,10 @@ def MFENCE : I<0xAE, MRM6m, (ops),
|
||||
|
||||
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
||||
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
||||
def V_SETALLONES : PDI<0x76, MRMInitReg, (ops VR128:$dst),
|
||||
"pcmpeqd $dst, $dst",
|
||||
[(set VR128:$dst, (v2f64 immAllOnesV))]>;
|
||||
let isReMaterializable = 1 in
|
||||
def V_SETALLONES : PDI<0x76, MRMInitReg, (ops VR128:$dst),
|
||||
"pcmpeqd $dst, $dst",
|
||||
[(set VR128:$dst, (v2f64 immAllOnesV))]>;
|
||||
|
||||
// FR64 to 128-bit vector conversion.
|
||||
def MOVSD2PDrr : SDI<0x10, MRMSrcReg, (ops VR128:$dst, FR64:$src),
|
||||
|
@ -91,6 +91,7 @@ namespace llvm {
|
||||
bool isConvertibleToThreeAddress;
|
||||
bool isCommutable;
|
||||
bool isTerminator;
|
||||
bool isReMaterializable;
|
||||
bool hasDelaySlot;
|
||||
bool usesCustomDAGSchedInserter;
|
||||
bool hasVariableNumberOfOperands;
|
||||
|
@ -365,6 +365,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
||||
isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
|
||||
isCommutable = R->getValueAsBit("isCommutable");
|
||||
isTerminator = R->getValueAsBit("isTerminator");
|
||||
isReMaterializable = R->getValueAsBit("isReMaterializable");
|
||||
hasDelaySlot = R->getValueAsBit("hasDelaySlot");
|
||||
usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
|
||||
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
|
||||
|
@ -240,6 +240,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR";
|
||||
if (Inst.isCommutable) OS << "|M_COMMUTABLE";
|
||||
if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
|
||||
if (Inst.isReMaterializable) OS << "|M_REMATERIALIZIBLE";
|
||||
if (Inst.clobbersPred) OS << "|M_CLOBBERS_PRED";
|
||||
if (Inst.isNotDuplicable) OS << "|M_NOT_DUPLICABLE";
|
||||
if (Inst.usesCustomDAGSchedInserter)
|
||||
|
Loading…
Reference in New Issue
Block a user