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:
Jakob Stoklund Olesen 2010-07-02 22:29:50 +00:00
parent f5cd8c51e3
commit a4e1ba53dd
5 changed files with 66 additions and 3 deletions

View File

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

View File

@ -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;
}
}
//===----------------------------------------------------------------------===//

View File

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

View File

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

View File

@ -344,6 +344,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
"COPY_TO_REGCLASS",
"DBG_VALUE",
"REG_SEQUENCE",
"COPY",
0
};
const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();