mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 03:32:10 +00:00
Add a new target independent COPY instruction and code to lower it.
The COPY instruction is intended to replace the target specific copy instructions for virtual registers as well as the EXTRACT_SUBREG and INSERT_SUBREG instructions in MachineFunctions. It won't we used in a selection DAG. COPY is lowered to native register copies by LowerSubregs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107529 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f5cd8c51e3
commit
a4e1ba53dd
@ -227,7 +227,10 @@ public:
|
||||
bool isRegSequence() const {
|
||||
return getOpcode() == TargetOpcode::REG_SEQUENCE;
|
||||
}
|
||||
|
||||
bool isCopy() const {
|
||||
return getOpcode() == TargetOpcode::COPY;
|
||||
}
|
||||
|
||||
/// readsRegister - Return true if the MachineInstr reads the specified
|
||||
/// register. If TargetRegisterInfo is passed, then it also checks if there
|
||||
/// is a read of a super-register.
|
||||
|
@ -476,7 +476,6 @@ def DBG_VALUE : Instruction {
|
||||
let AsmString = "DBG_VALUE";
|
||||
let isAsCheapAsAMove = 1;
|
||||
}
|
||||
|
||||
def REG_SEQUENCE : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins variable_ops);
|
||||
@ -484,6 +483,13 @@ def REG_SEQUENCE : Instruction {
|
||||
let neverHasSideEffects = 1;
|
||||
let isAsCheapAsAMove = 1;
|
||||
}
|
||||
def COPY : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins unknown:$src);
|
||||
let AsmString = "";
|
||||
let neverHasSideEffects = 1;
|
||||
let isAsCheapAsAMove = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -75,7 +75,11 @@ namespace TargetOpcode {
|
||||
/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
|
||||
/// After register coalescing references of v1024 should be replace with
|
||||
/// v1027:3, v1025 with v1027:4, etc.
|
||||
REG_SEQUENCE = 12
|
||||
REG_SEQUENCE = 12,
|
||||
|
||||
/// COPY - Target-independent register copy. This instruction can also be
|
||||
/// used to copy between subregisters of virtual registers.
|
||||
COPY = 13
|
||||
};
|
||||
} // end namespace TargetOpcode
|
||||
} // end namespace llvm
|
||||
|
@ -56,6 +56,7 @@ namespace {
|
||||
bool LowerExtract(MachineInstr *MI);
|
||||
bool LowerInsert(MachineInstr *MI);
|
||||
bool LowerSubregToReg(MachineInstr *MI);
|
||||
bool LowerCopy(MachineInstr *MI);
|
||||
|
||||
void TransferDeadFlag(MachineInstr *MI, unsigned DstReg,
|
||||
const TargetRegisterInfo *TRI);
|
||||
@ -321,6 +322,52 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) {
|
||||
MachineOperand &DstMO = MI->getOperand(0);
|
||||
MachineOperand &SrcMO = MI->getOperand(1);
|
||||
|
||||
if (SrcMO.getReg() == DstMO.getReg()) {
|
||||
DEBUG(dbgs() << "identity copy: " << *MI);
|
||||
// No need to insert an identity copy instruction, but replace with a KILL
|
||||
// if liveness is changed.
|
||||
if (DstMO.isDead() || SrcMO.isUndef() || MI->getNumOperands() > 2) {
|
||||
// We must make sure the super-register gets killed. Replace the
|
||||
// instruction with KILL.
|
||||
MI->setDesc(TII->get(TargetOpcode::KILL));
|
||||
DEBUG(dbgs() << "replaced by: " << *MI);
|
||||
return true;
|
||||
}
|
||||
// Vanilla identity copy.
|
||||
MI->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << "real copy: " << *MI);
|
||||
// Ask target for a lowered copy instruction.
|
||||
const TargetRegisterClass *DstRC =
|
||||
TRI->getPhysicalRegisterRegClass(DstMO.getReg());
|
||||
const TargetRegisterClass *SrcRC =
|
||||
TRI->getPhysicalRegisterRegClass(SrcMO.getReg());
|
||||
bool Emitted = TII->copyRegToReg(*MI->getParent(), MI,
|
||||
DstMO.getReg(), SrcMO.getReg(),
|
||||
DstRC, SrcRC, MI->getDebugLoc());
|
||||
(void)Emitted;
|
||||
assert(Emitted && "Cannot emit copy");
|
||||
|
||||
if (DstMO.isDead())
|
||||
TransferDeadFlag(MI, DstMO.getReg(), TRI);
|
||||
if (SrcMO.isKill())
|
||||
TransferKillFlag(MI, SrcMO.getReg(), TRI, true);
|
||||
if (MI->getNumOperands() > 2)
|
||||
TransferImplicitDefs(MI);
|
||||
DEBUG({
|
||||
MachineBasicBlock::iterator dMI = MI;
|
||||
dbgs() << "replaced by: " << *(--dMI);
|
||||
});
|
||||
MI->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - Reduce subregister inserts and extracts to register
|
||||
/// copies.
|
||||
///
|
||||
@ -346,6 +393,8 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
|
||||
MadeChange |= LowerInsert(MI);
|
||||
} else if (MI->isSubregToReg()) {
|
||||
MadeChange |= LowerSubregToReg(MI);
|
||||
} else if (MI->isCopy()) {
|
||||
MadeChange |= LowerCopy(MI);
|
||||
}
|
||||
mi = nmi;
|
||||
}
|
||||
|
@ -344,6 +344,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
|
||||
"COPY_TO_REGCLASS",
|
||||
"DBG_VALUE",
|
||||
"REG_SEQUENCE",
|
||||
"COPY",
|
||||
0
|
||||
};
|
||||
const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
|
||||
|
Loading…
x
Reference in New Issue
Block a user