mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-24 12:29:33 +00:00
Collect and coalesce DBG_VALUE instructions before emitting the function.
Correctly terminate the range of register DBG_VALUEs when the register is clobbered or when the basic block ends. The code is now ready to deal with variables that are sometimes in a register and sometimes on the stack. We just need to teach emitDebugLoc to say 'stack slot'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128327 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eca915fb52
commit
adb877d62e
include/llvm/CodeGen
lib/CodeGen/AsmPrinter
test/CodeGen/X86
@ -309,6 +309,10 @@ public:
|
||||
/// instruction in the basic block, or end()
|
||||
iterator getLastNonDebugInstr();
|
||||
|
||||
const_iterator getLastNonDebugInstr() const {
|
||||
return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
|
||||
}
|
||||
|
||||
/// SplitCriticalEdge - Split the critical edge from this block to the
|
||||
/// given successor block, and return the newly created block, or null
|
||||
/// if splitting is not possible.
|
||||
|
@ -2408,38 +2408,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
/// collection info from MMI table.
|
||||
collectVariableInfoFromMMITable(MF, Processed);
|
||||
|
||||
SmallVector<const MachineInstr *, 8> DbgValues;
|
||||
// Collect variable information from DBG_VALUE machine instructions;
|
||||
for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
|
||||
I != E; ++I)
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
||||
II != IE; ++II) {
|
||||
const MachineInstr *MInsn = II;
|
||||
if (!MInsn->isDebugValue())
|
||||
continue;
|
||||
DbgValues.push_back(MInsn);
|
||||
}
|
||||
|
||||
// This is a collection of DBG_VALUE instructions describing same variable.
|
||||
SmallVector<const MachineInstr *, 4> MultipleValues;
|
||||
for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
|
||||
E = DbgValues.end(); I != E; ++I) {
|
||||
const MachineInstr *MInsn = *I;
|
||||
MultipleValues.clear();
|
||||
if (isDbgValueInDefinedReg(MInsn))
|
||||
MultipleValues.push_back(MInsn);
|
||||
DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata());
|
||||
if (Processed.count(DV) != 0)
|
||||
for (SmallVectorImpl<const MDNode*>::const_iterator
|
||||
UVI = UserVariables.begin(), UVE = UserVariables.end(); UVI != UVE;
|
||||
++UVI) {
|
||||
const MDNode *Var = *UVI;
|
||||
if (Processed.count(Var))
|
||||
continue;
|
||||
|
||||
for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1,
|
||||
ME = DbgValues.end(); MI != ME; ++MI) {
|
||||
const MDNode *Var =
|
||||
(*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
|
||||
if (Var == DV)
|
||||
MultipleValues.push_back(*MI);
|
||||
}
|
||||
// History contains relevant DBG_VALUE instructions for Var and instructions
|
||||
// clobbering it.
|
||||
SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
|
||||
if (History.empty())
|
||||
continue;
|
||||
const MachineInstr *MInsn = History.front();
|
||||
|
||||
DIVariable DV(Var);
|
||||
DbgScope *Scope = NULL;
|
||||
if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
|
||||
DISubprogram(DV.getContext()).describes(MF->getFunction()))
|
||||
@ -2451,6 +2434,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
continue;
|
||||
|
||||
Processed.insert(DV);
|
||||
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
||||
DbgVariable *RegVar = new DbgVariable(DV);
|
||||
if (!addCurrentFnArgument(MF, RegVar, Scope))
|
||||
Scope->addVariable(RegVar);
|
||||
@ -2458,21 +2442,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
DbgVariableToDbgInstMap[AbsVar] = MInsn;
|
||||
VarToAbstractVarMap[RegVar] = AbsVar;
|
||||
}
|
||||
if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
|
||||
|
||||
// Simple ranges that are fully coalesced.
|
||||
if (History.size() <= 1 || (History.size() == 2 &&
|
||||
MInsn->isIdenticalTo(History.back()))) {
|
||||
DbgVariableToDbgInstMap[RegVar] = MInsn;
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle multiple DBG_VALUE instructions describing one variable.
|
||||
if (DotDebugLocEntries.empty())
|
||||
RegVar->setDotDebugLocOffset(0);
|
||||
else
|
||||
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
|
||||
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
|
||||
|
||||
for (SmallVector<const MachineInstr *, 4>::iterator
|
||||
MVI = MultipleValues.begin(), MVE = MultipleValues.end();
|
||||
MVI != MVE; ++MVI) {
|
||||
const MachineInstr *Begin = *MVI;
|
||||
for (SmallVectorImpl<const MachineInstr*>::const_iterator
|
||||
HI = History.begin(), HE = History.end(); HI != HE; ++HI) {
|
||||
const MachineInstr *Begin = *HI;
|
||||
assert(Begin->isDebugValue() && "Invalid History entry");
|
||||
MachineLocation MLoc;
|
||||
if (Begin->getNumOperands() == 3) {
|
||||
if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
|
||||
@ -2480,6 +2464,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
} else
|
||||
MLoc = Asm->getDebugValueLocation(Begin);
|
||||
|
||||
// FIXME: emitDebugLoc only understands registers.
|
||||
if (!MLoc.getReg())
|
||||
continue;
|
||||
|
||||
@ -2487,17 +2472,23 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
|
||||
const MCSymbol *SLabel = 0;
|
||||
|
||||
if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
|
||||
// The register range starting at Begin may be clobbered.
|
||||
SLabel = getLabelAfterInsn(ClobberMI);
|
||||
else if (MVI + 1 == MVE)
|
||||
// If Begin is the last instruction then its value is valid
|
||||
if (HI + 1 == HE)
|
||||
// If Begin is the last instruction in History then its value is valid
|
||||
// until the end of the funtion.
|
||||
SLabel = FunctionEndSym;
|
||||
else
|
||||
// The value is valid until the next DBG_VALUE.
|
||||
SLabel = getLabelBeforeInsn(MVI[1]);
|
||||
else {
|
||||
const MachineInstr *End = HI[1];
|
||||
if (End->isDebugValue())
|
||||
SLabel = getLabelBeforeInsn(End);
|
||||
else {
|
||||
// End is a normal instruction clobbering the range.
|
||||
SLabel = getLabelAfterInsn(End);
|
||||
assert(SLabel && "Forgot label after clobber instruction");
|
||||
++HI;
|
||||
}
|
||||
}
|
||||
|
||||
// The value is valid until the next DBG_VALUE or clobber.
|
||||
DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
|
||||
}
|
||||
DotDebugLocEntries.push_back(DotDebugLocEntry());
|
||||
@ -2519,21 +2510,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
|
||||
/// getLabelBeforeInsn - Return Label preceding the instruction.
|
||||
const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
|
||||
DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
|
||||
LabelsBeforeInsn.find(MI);
|
||||
if (I == LabelsBeforeInsn.end())
|
||||
// FunctionBeginSym always preceeds all the instruction in current function.
|
||||
return FunctionBeginSym;
|
||||
return I->second;
|
||||
MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
|
||||
assert(Label && "Didn't insert label before instruction");
|
||||
return Label;
|
||||
}
|
||||
|
||||
/// getLabelAfterInsn - Return Label immediately following the instruction.
|
||||
const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
|
||||
DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
|
||||
LabelsAfterInsn.find(MI);
|
||||
if (I == LabelsAfterInsn.end())
|
||||
return NULL;
|
||||
return I->second;
|
||||
return LabelsAfterInsn.lookup(MI);
|
||||
}
|
||||
|
||||
/// beginInstruction - Process beginning of an instruction.
|
||||
@ -2552,14 +2536,22 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
|
||||
}
|
||||
|
||||
// Insert labels where requested.
|
||||
if (!InsnNeedsLabel.count(MI))
|
||||
DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
|
||||
LabelsBeforeInsn.find(MI);
|
||||
|
||||
// No label needed.
|
||||
if (I == LabelsBeforeInsn.end())
|
||||
return;
|
||||
|
||||
// Label already assigned.
|
||||
if (I->second)
|
||||
return;
|
||||
|
||||
if (!PrevLabel) {
|
||||
PrevLabel = MMI->getContext().CreateTempSymbol();
|
||||
Asm->OutStreamer.EmitLabel(PrevLabel);
|
||||
}
|
||||
LabelsBeforeInsn[MI] = PrevLabel;
|
||||
I->second = PrevLabel;
|
||||
}
|
||||
|
||||
/// endInstruction - Process end of an instruction.
|
||||
@ -2569,7 +2561,15 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
|
||||
if (!MI->isDebugValue())
|
||||
PrevLabel = 0;
|
||||
|
||||
if (!InsnsNeedsLabelAfter.count(MI))
|
||||
DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
|
||||
LabelsAfterInsn.find(MI);
|
||||
|
||||
// No label needed.
|
||||
if (I == LabelsAfterInsn.end())
|
||||
return;
|
||||
|
||||
// Label already assigned.
|
||||
if (I->second)
|
||||
return;
|
||||
|
||||
// We need a label after this instruction.
|
||||
@ -2577,7 +2577,7 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
|
||||
PrevLabel = MMI->getContext().CreateTempSymbol();
|
||||
Asm->OutStreamer.EmitLabel(PrevLabel);
|
||||
}
|
||||
LabelsAfterInsn[MI] = PrevLabel;
|
||||
I->second = PrevLabel;
|
||||
}
|
||||
|
||||
/// getOrCreateDbgScope - Create DbgScope for the scope.
|
||||
@ -2837,8 +2837,8 @@ void DwarfDebug::identifyScopeMarkers() {
|
||||
RE = Ranges.end(); RI != RE; ++RI) {
|
||||
assert(RI->first && "DbgRange does not have first instruction!");
|
||||
assert(RI->second && "DbgRange does not have second instruction!");
|
||||
InsnNeedsLabel.insert(RI->first);
|
||||
InsnsNeedsLabelAfter.insert(RI->second);
|
||||
requestLabelBeforeInsn(RI->first);
|
||||
requestLabelAfterInsn(RI->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2916,46 +2916,78 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
|
||||
recordSourceLine(Line, Col, TheScope);
|
||||
|
||||
assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned");
|
||||
|
||||
/// ProcessedArgs - Collection of arguments already processed.
|
||||
SmallPtrSet<const MDNode *, 8> ProcessedArgs;
|
||||
|
||||
/// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
|
||||
DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
|
||||
|
||||
const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
|
||||
|
||||
/// LiveUserVar - Map physreg numbers to the MDNode they contain.
|
||||
std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
|
||||
|
||||
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
|
||||
I != E; ++I)
|
||||
I != E; ++I) {
|
||||
bool AtBlockEntry = true;
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
||||
II != IE; ++II) {
|
||||
const MachineInstr *MI = II;
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
|
||||
if (MI->isDebugValue()) {
|
||||
assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
|
||||
|
||||
// Keep track of variables in registers.
|
||||
// Keep track of user variables.
|
||||
const MDNode *Var =
|
||||
MI->getOperand(MI->getNumOperands() - 1).getMetadata();
|
||||
LastDbgValue[Var] = MI;
|
||||
|
||||
// Variable is in a register, we need to check for clobbers.
|
||||
if (isDbgValueInDefinedReg(MI))
|
||||
LiveUserVar[MI->getOperand(0).getReg()] = Var;
|
||||
|
||||
DIVariable DV(Var);
|
||||
if (!DV.Verify()) continue;
|
||||
// If DBG_VALUE is for a local variable then it needs a label.
|
||||
if (DV.getTag() != dwarf::DW_TAG_arg_variable)
|
||||
InsnNeedsLabel.insert(MI);
|
||||
// DBG_VALUE for inlined functions argument needs a label.
|
||||
else if (!DISubprogram(getDISubprogram(DV.getContext())).
|
||||
describes(MF->getFunction()))
|
||||
InsnNeedsLabel.insert(MI);
|
||||
// DBG_VALUE indicating argument location change needs a label.
|
||||
else if (!ProcessedArgs.insert(DV))
|
||||
InsnNeedsLabel.insert(MI);
|
||||
// Check the history of this variable.
|
||||
SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
|
||||
if (History.empty()) {
|
||||
UserVariables.push_back(Var);
|
||||
// The first mention of a function argument gets the FunctionBeginSym
|
||||
// label, so arguments are visible when breaking at function entry.
|
||||
DIVariable DV(Var);
|
||||
if (DV.Verify() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
|
||||
DISubprogram(getDISubprogram(DV.getContext()))
|
||||
.describes(MF->getFunction()))
|
||||
LabelsBeforeInsn[MI] = FunctionBeginSym;
|
||||
} else {
|
||||
// We have seen this variable before. Try to coalesce DBG_VALUEs.
|
||||
const MachineInstr *Prev = History.back();
|
||||
if (Prev->isDebugValue()) {
|
||||
// Coalesce identical entries at the end of History.
|
||||
if (History.size() >= 2 &&
|
||||
Prev->isIdenticalTo(History[History.size() - 2]))
|
||||
History.pop_back();
|
||||
|
||||
// Terminate old register assignments that don't reach MI;
|
||||
MachineFunction::const_iterator PrevMBB = Prev->getParent();
|
||||
if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB) != I) &&
|
||||
isDbgValueInDefinedReg(Prev)) {
|
||||
// Previous register assignment needs to terminate at the end of
|
||||
// its basic block.
|
||||
MachineBasicBlock::const_iterator LastMI =
|
||||
PrevMBB->getLastNonDebugInstr();
|
||||
if (LastMI == PrevMBB->end())
|
||||
// Drop DBG_VALUE for empty range.
|
||||
History.pop_back();
|
||||
else {
|
||||
// Terminate after LastMI.
|
||||
History.push_back(LastMI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
History.push_back(MI);
|
||||
} else {
|
||||
// Not a DBG_VALUE instruction.
|
||||
if (!MI->isLabel())
|
||||
AtBlockEntry = false;
|
||||
|
||||
// Check if the instruction clobbers any registers with debug vars.
|
||||
for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
|
||||
MOE = MI->operands_end(); MOI != MOE; ++MOI) {
|
||||
@ -2970,19 +3002,57 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
LiveUserVar[Reg] = 0;
|
||||
|
||||
// Was MD last defined by a DBG_VALUE referring to Reg?
|
||||
const MachineInstr *Last = LastDbgValue.lookup(Var);
|
||||
if (!Last || Last->getParent() != MI->getParent())
|
||||
DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
|
||||
if (HistI == DbgValues.end())
|
||||
continue;
|
||||
if (!isDbgValueInDefinedReg(Last) ||
|
||||
Last->getOperand(0).getReg() != Reg)
|
||||
SmallVectorImpl<const MachineInstr*> &History = HistI->second;
|
||||
if (History.empty())
|
||||
continue;
|
||||
// MD is clobbered. Make sure the next instruction gets a label.
|
||||
InsnsNeedsLabelAfter.insert(MI);
|
||||
RegClobberInsn[Last] = MI;
|
||||
const MachineInstr *Prev = History.back();
|
||||
// Sanity-check: Register assignments are terminated at the end of
|
||||
// their block.
|
||||
if (!Prev->isDebugValue() || Prev->getParent() != MI->getParent())
|
||||
continue;
|
||||
// Is the variable still in Reg?
|
||||
if (!isDbgValueInDefinedReg(Prev) ||
|
||||
Prev->getOperand(0).getReg() != Reg)
|
||||
continue;
|
||||
// Var is clobbered. Make sure the next instruction gets a label.
|
||||
History.push_back(MI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E = DbgValues.end();
|
||||
I != E; ++I) {
|
||||
SmallVectorImpl<const MachineInstr*> &History = I->second;
|
||||
if (History.empty())
|
||||
continue;
|
||||
|
||||
// Make sure the final register assignments are terminated.
|
||||
const MachineInstr *Prev = History.back();
|
||||
if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {
|
||||
const MachineBasicBlock *PrevMBB = Prev->getParent();
|
||||
MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr();
|
||||
if (LastMI == PrevMBB->end())
|
||||
// Drop DBG_VALUE for empty range.
|
||||
History.pop_back();
|
||||
else {
|
||||
// Terminate after LastMI.
|
||||
History.push_back(LastMI);
|
||||
}
|
||||
}
|
||||
// Request labels for the full history.
|
||||
for (unsigned i = 0, e = History.size(); i != e; ++i) {
|
||||
const MachineInstr *MI = History[i];
|
||||
if (MI->isDebugValue())
|
||||
requestLabelBeforeInsn(MI);
|
||||
else
|
||||
requestLabelAfterInsn(MI);
|
||||
}
|
||||
}
|
||||
|
||||
PrevInstLoc = DebugLoc();
|
||||
PrevLabel = FunctionBeginSym;
|
||||
@ -3043,13 +3113,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
||||
// Clear debug info
|
||||
CurrentFnDbgScope = NULL;
|
||||
CurrentFnArguments.clear();
|
||||
InsnNeedsLabel.clear();
|
||||
DbgVariableToFrameIndexMap.clear();
|
||||
VarToAbstractVarMap.clear();
|
||||
DbgVariableToDbgInstMap.clear();
|
||||
DeleteContainerSeconds(DbgScopeMap);
|
||||
InsnsNeedsLabelAfter.clear();
|
||||
RegClobberInsn.clear();
|
||||
UserVariables.clear();
|
||||
DbgValues.clear();
|
||||
ConcreteScopes.clear();
|
||||
DeleteContainerSeconds(AbstractScopes);
|
||||
AbstractScopesList.clear();
|
||||
|
@ -218,19 +218,16 @@ class DwarfDebug {
|
||||
/// instruction.
|
||||
DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
|
||||
|
||||
/// insnNeedsLabel - Collection of instructions that need a label to mark
|
||||
/// a debuggging information entity.
|
||||
SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
|
||||
/// UserVariables - Every user variable mentioned by a DBG_VALUE instruction
|
||||
/// in order of appearance.
|
||||
SmallVector<const MDNode*, 8> UserVariables;
|
||||
|
||||
/// InsnsNeedsLabelAfter - Collection of instructions that need a label after
|
||||
/// the instruction because they end a scope of clobber a register.
|
||||
SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;
|
||||
|
||||
/// RegClobberInsn - For each DBG_VALUE instruction referring to a register
|
||||
/// that is clobbered before the variable gets a new DBG_VALUE, map the
|
||||
/// instruction that clobbered the register. This instruction will also be in
|
||||
/// InsnsNeedsLabelAfter.
|
||||
DenseMap<const MachineInstr *, const MachineInstr *> RegClobberInsn;
|
||||
/// DbgValues - For each user variable, keep a list of DBG_VALUE
|
||||
/// instructions in order. The list can also contain normal instructions that
|
||||
/// clobber the previous DBG_VALUE.
|
||||
typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> >
|
||||
DbgValueHistoryMap;
|
||||
DbgValueHistoryMap DbgValues;
|
||||
|
||||
SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
|
||||
|
||||
@ -570,6 +567,23 @@ private:
|
||||
/// side table maintained by MMI.
|
||||
void collectVariableInfoFromMMITable(const MachineFunction * MF,
|
||||
SmallPtrSet<const MDNode *, 16> &P);
|
||||
|
||||
/// requestLabelBeforeInsn - Ensure that a label will be emitted before MI.
|
||||
void requestLabelBeforeInsn(const MachineInstr *MI) {
|
||||
LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));
|
||||
}
|
||||
|
||||
/// getLabelBeforeInsn - Return Label preceding the instruction.
|
||||
const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
|
||||
|
||||
/// requestLabelAfterInsn - Ensure that a label will be emitted after MI.
|
||||
void requestLabelAfterInsn(const MachineInstr *MI) {
|
||||
LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));
|
||||
}
|
||||
|
||||
/// getLabelAfterInsn - Return Label immediately following the instruction.
|
||||
const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
|
||||
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Main entry points.
|
||||
@ -593,12 +607,6 @@ public:
|
||||
///
|
||||
void endFunction(const MachineFunction *MF);
|
||||
|
||||
/// getLabelBeforeInsn - Return Label preceding the instruction.
|
||||
const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
|
||||
|
||||
/// getLabelAfterInsn - Return Label immediately following the instruction.
|
||||
const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
|
||||
|
||||
/// beginInstruction - Process beginning of an instruction.
|
||||
void beginInstruction(const MachineInstr *MI);
|
||||
|
||||
|
@ -4,7 +4,7 @@ target triple = "x86_64-apple-darwin8"
|
||||
|
||||
;CHECK: Ldebug_loc0:
|
||||
;CHECK-NEXT: .quad Lfunc_begin0
|
||||
;CHECK-NEXT: .quad Lfunc_end0
|
||||
;CHECK-NEXT: .quad L
|
||||
;CHECK-NEXT: .short 1 ## Loc expr size
|
||||
;CHECK-NEXT: .byte 85 ## DW_OP_reg5
|
||||
;CHECK-NEXT: .quad 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user