summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-02 22:29:50 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-02 22:29:50 +0000
commit676a15bdf5068aba670b122ccc7445c84bb48b22 (patch)
tree1ade653737281134fb2c5543c78507a8fe3fd0d7 /llvm/lib
parent248e64b5b854122695b36bf655c06a87c9b2020c (diff)
downloadbcm5719-llvm-676a15bdf5068aba670b122ccc7445c84bb48b22.tar.gz
bcm5719-llvm-676a15bdf5068aba670b122ccc7445c84bb48b22.zip
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. llvm-svn: 107529
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/LowerSubregs.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/LowerSubregs.cpp b/llvm/lib/CodeGen/LowerSubregs.cpp
index 2dfd07f7f23..172e4b57950 100644
--- a/llvm/lib/CodeGen/LowerSubregs.cpp
+++ b/llvm/lib/CodeGen/LowerSubregs.cpp
@@ -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;
}
OpenPOWER on IntegriCloud