aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-07-03 23:56:20 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-07-03 23:56:20 +0000
commitf64765244512250b28b1fbe290b1b26d17e41dd4 (patch)
treed10880574ee192b55521a558b84b33c9d86fe2f0
parent62da588a2eb70166e1b6cc332d8084f03117dc12 (diff)
downloadexternal_llvm-f64765244512250b28b1fbe290b1b26d17e41dd4.zip
external_llvm-f64765244512250b28b1fbe290b1b26d17e41dd4.tar.gz
external_llvm-f64765244512250b28b1fbe290b1b26d17e41dd4.tar.bz2
Add MachineBasicBlock::addLiveIn().
This function adds a live-in physical register to an MBB and ensures that it is copied to a virtual register immediately. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185594 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h5
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp33
2 files changed, 38 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 0f2f874..d6f5883 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -296,6 +296,11 @@ public:
/// is an error to add the same register to the same set more than once.
void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+ /// Add PhysReg as live in to this block, and ensure that there is a copy of
+ /// PhysReg to a virtual register of class RC. Return the virtual register
+ /// that is a copy of the live in PhysReg.
+ unsigned addLiveIn(unsigned PhysReg, const TargetRegisterClass *RC);
+
/// removeLiveIn - Remove the specified register from the live in set.
///
void removeLiveIn(unsigned Reg);
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index feba078..7bb0d32 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
@@ -341,6 +342,38 @@ bool MachineBasicBlock::isLiveIn(unsigned Reg) const {
return I != livein_end();
}
+unsigned
+MachineBasicBlock::addLiveIn(unsigned PhysReg, const TargetRegisterClass *RC) {
+ assert(getParent() && "MBB must be inserted in function");
+ assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Expected physreg");
+ assert(RC && "Register class is required");
+ assert((isLandingPad() || this == &getParent()->front()) &&
+ "Only the entry block and landing pads can have physreg live ins");
+
+ bool LiveIn = isLiveIn(PhysReg);
+ iterator I = getFirstNonPHI(), E = end();
+ MachineRegisterInfo &MRI = getParent()->getRegInfo();
+ const TargetInstrInfo &TII = *getParent()->getTarget().getInstrInfo();
+
+ // Look for an existing copy.
+ if (LiveIn)
+ for (;I != E && I->isCopy(); ++I)
+ if (I->getOperand(1).getReg() == PhysReg) {
+ unsigned VirtReg = I->getOperand(0).getReg();
+ if (!MRI.constrainRegClass(VirtReg, RC))
+ llvm_unreachable("Incompatible live-in register class.");
+ return VirtReg;
+ }
+
+ // No luck, create a virtual register.
+ unsigned VirtReg = MRI.createVirtualRegister(RC);
+ BuildMI(*this, I, DebugLoc(), TII.get(TargetOpcode::COPY), VirtReg)
+ .addReg(PhysReg, RegState::Kill);
+ if (!LiveIn)
+ addLiveIn(PhysReg);
+ return VirtReg;
+}
+
void MachineBasicBlock::moveBefore(MachineBasicBlock *NewAfter) {
getParent()->splice(NewAfter, this);
}