Replace r102368 with code that's less fragile. This creates DBG_VALUE instructions for function arguments early and insert them after instruction selection is done.

llvm-svn: 102554
This commit is contained in:
Evan Cheng 2010-04-28 23:08:54 +00:00
parent 45c337c939
commit a02c9072fc
7 changed files with 81 additions and 33 deletions

View File

@ -261,6 +261,10 @@ public:
bool isLiveIn(unsigned Reg) const;
bool isLiveOut(unsigned Reg) const;
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
unsigned getLiveInPhysReg(unsigned VReg) const;
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
/// into the given entry block.
void EmitLiveInCopies(MachineBasicBlock *EntryMBB,

View File

@ -147,6 +147,15 @@ bool MachineRegisterInfo::isLiveOut(unsigned Reg) const {
return false;
}
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
unsigned MachineRegisterInfo::getLiveInPhysReg(unsigned VReg) const {
for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
if (I->second == VReg)
return I->first;
return 0;
}
static cl::opt<bool>
SchedLiveInCopies("schedule-livein-copies", cl::Hidden,
cl::desc("Schedule copies of livein registers"),
@ -220,30 +229,6 @@ static void EmitLiveInCopy(MachineBasicBlock *MBB,
}
}
/// InsertLiveInDbgValue - Insert a DBG_VALUE instruction for each live-in
/// register that has a corresponding source information metadata. e.g.
/// function parameters.
static void InsertLiveInDbgValue(MachineBasicBlock *MBB,
MachineBasicBlock::iterator InsertPos,
unsigned LiveInReg, unsigned VirtReg,
const MachineRegisterInfo &MRI,
const TargetInstrInfo &TII) {
for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg),
UE = MRI.use_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
if (!UseMI->isDebugValue() || UseMI->getParent() != MBB)
continue;
// Found local dbg_value. FIXME: Verify it's not possible to have multiple
// dbg_value's which reference the vr in the same mbb.
uint64_t Offset = UseMI->getOperand(1).getImm();
const MDNode *MDPtr = UseMI->getOperand(2).getMetadata();
BuildMI(*MBB, InsertPos, InsertPos->getDebugLoc(),
TII.get(TargetOpcode::DBG_VALUE))
.addReg(LiveInReg).addImm(Offset).addMetadata(MDPtr);
return;
}
}
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
/// into the given entry block.
void
@ -260,8 +245,6 @@ MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
const TargetRegisterClass *RC = getRegClass(LI->second);
EmitLiveInCopy(EntryMBB, InsertPos, LI->second, LI->first,
RC, CopyRegMap, *this, TRI, TII);
InsertLiveInDbgValue(EntryMBB, InsertPos,
LI->first, LI->second, *this, TII);
}
} else {
// Emit the copies into the top of the block.
@ -273,8 +256,6 @@ MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
LI->second, LI->first, RC, RC);
assert(Emitted && "Unable to issue a live-in copy instruction!\n");
(void) Emitted;
InsertLiveInDbgValue(EntryMBB, EntryMBB->begin(),
LI->first, LI->second, *this, TII);
}
}

View File

@ -173,6 +173,7 @@ void FunctionLoweringInfo::clear() {
CatchInfoFound.clear();
#endif
LiveOutRegInfo.clear();
ArgDbgValues.clear();
}
unsigned FunctionLoweringInfo::MakeReg(EVT VT) {

View File

@ -75,6 +75,8 @@ public:
/// anywhere in the function.
DenseMap<const AllocaInst*, int> StaticAllocaMap;
SmallVector<MachineInstr*, 8> ArgDbgValues;
#ifndef NDEBUG
SmallSet<const Instruction *, 8> CatchInfoLost;
SmallSet<const Instruction *, 8> CatchInfoFound;

View File

@ -3681,6 +3681,41 @@ static SDValue ExpandPowI(DebugLoc DL, SDValue LHS, SDValue RHS,
return DAG.getNode(ISD::FPOWI, DL, LHS.getValueType(), LHS, RHS);
}
/// EmitFuncArgumentDbgValue - If the DbgValueInst is a dbg_value of a function
/// argument, create the corresponding DBG_VALUE machine instruction for it now.
/// At the end of instruction selection, they will be inserted to the entry BB.
void
SelectionDAGBuilder::EmitFuncArgumentDbgValue(const DbgValueInst &DI,
const Value *V, MDNode *Variable,
uint64_t Offset, SDValue &N) {
if (!isa<Argument>(V))
return;
MachineFunction &MF = DAG.getMachineFunction();
MachineBasicBlock *MBB = FuncInfo.MBBMap[DI.getParent()];
if (MBB != &MF.front())
return;
unsigned Reg = 0;
if (N.getOpcode() == ISD::CopyFromReg) {
Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
MachineRegisterInfo &RegInfo = MF.getRegInfo();
unsigned PR = RegInfo.getLiveInPhysReg(Reg);
if (PR)
Reg = PR;
}
}
if (!Reg)
Reg = FuncInfo.ValueMap[V];
const TargetInstrInfo *TII = DAG.getTarget().getInstrInfo();
MachineInstrBuilder MIB = BuildMI(MF, getCurDebugLoc(),
TII->get(TargetOpcode::DBG_VALUE))
.addReg(Reg).addImm(Offset).addMetadata(Variable);
FuncInfo.ArgDbgValues.push_back(&*MIB);
}
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
/// we want to emit this as a call to a named external function, return the name
@ -3864,6 +3899,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
} else {
SDValue &N = NodeMap[V];
if (N.getNode()) {
EmitFuncArgumentDbgValue(DI, V, Variable, Offset, N);
SDV = DAG.getDbgValue(Variable, N.getNode(),
N.getResNo(), Offset, dl, SDNodeOrder);
DAG.AddDbgValue(SDV, N.getNode(), false);

View File

@ -36,6 +36,7 @@ class BasicBlock;
class BitCastInst;
class BranchInst;
class CallInst;
class DbgValueInst;
class ExtractElementInst;
class ExtractValueInst;
class FCmpInst;
@ -58,6 +59,7 @@ class LoadInst;
class MachineBasicBlock;
class MachineInstr;
class MachineRegisterInfo;
class MDNode;
class PHINode;
class PtrToIntInst;
class ReturnInst;
@ -495,6 +497,14 @@ private:
const char *implVisitAluOverflow(const CallInst &I, ISD::NodeType Op);
void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
/// EmitFuncArgumentDbgValue - If the DbgValueInst is a dbg_value of a
/// function argument, create the corresponding DBG_VALUE machine instruction
/// for it now. At the end of instruction selection, they will be inserted to
/// the entry BB.
void EmitFuncArgumentDbgValue(const DbgValueInst &DI,
const Value *V, MDNode *Variable,
uint64_t Offset, SDValue &N);
};
} // end namespace llvm

View File

@ -212,14 +212,28 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
SelectAllBasicBlocks(Fn);
// Release function-specific state. SDB and CurDAG are already cleared
// at this point.
FuncInfo->clear();
// If the first basic block in the function has live ins that need to be
// copied into vregs, emit the copies into the top of the block before
// emitting the code for the block.
RegInfo->EmitLiveInCopies(MF->begin(), TRI, TII);
MachineBasicBlock *EntryMBB = MF->begin();
RegInfo->EmitLiveInCopies(EntryMBB, TRI, TII);
// Insert DBG_VALUE instructions for function arguments to the entry block.
for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1];
unsigned Reg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
EntryMBB->insert(EntryMBB->begin(), MI);
else {
MachineInstr *Def = RegInfo->getVRegDef(Reg);
MachineBasicBlock::iterator InsertPos = Def;
EntryMBB->insert(llvm::next(InsertPos), MI);
}
}
// Release function-specific state. SDB and CurDAG are already cleared
// at this point.
FuncInfo->clear();
return true;
}