Remember byval argument's frame index during argument lowering and use this info to emit debug info.

Fixes Radar 8367011.

llvm-svn: 112623
This commit is contained in:
Devang Patel 2010-08-31 18:50:09 +00:00
parent 6f6b590b99
commit 8559932d36
5 changed files with 112 additions and 4 deletions

View File

@ -77,6 +77,9 @@ public:
/// anywhere in the function.
DenseMap<const AllocaInst*, int> StaticAllocaMap;
/// ByValArgFrameIndexMap - Keep track of frame indices for byval arguments.
DenseMap<const Argument*, int> ByValArgFrameIndexMap;
/// ArgDbgValues - A list of DBG_VALUE instructions created during isel for
/// function arguments that are inserted after scheduling is completed.
SmallVector<MachineInstr*, 8> ArgDbgValues;
@ -138,6 +141,13 @@ public:
assert(R == 0 && "Already initialized this value register!");
return R = CreateRegs(V->getType());
}
/// setByValArgumentFrameIndex - Record frame index for the byval
/// argument.
void setByValArgumentFrameIndex(const Argument *A, int FI);
/// getByValArgumentFrameIndex - Get frame index for the byval argument.
int getByValArgumentFrameIndex(const Argument *A);
};
/// AddCatchInfo - Extract the personality and type infos from an eh.selector

View File

@ -1629,9 +1629,16 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
bool updated = false;
// FIXME : Handle getNumOperands != 3
if (DVInsn->getNumOperands() == 3) {
if (DVInsn->getOperand(0).isReg())
updated =
addRegisterAddress(VariableDie, DVLabel, DVInsn->getOperand(0));
if (DVInsn->getOperand(0).isReg()) {
const MachineOperand RegOp = DVInsn->getOperand(0);
const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
if (DVInsn->getOperand(1).isImm() &&
TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
addVariableAddress(DV, VariableDie, DVInsn->getOperand(1).getImm());
updated = true;
} else
updated = addRegisterAddress(VariableDie, DVLabel, RegOp);
}
else if (DVInsn->getOperand(0).isImm())
updated = addConstantValue(VariableDie, DVLabel, DVInsn->getOperand(0));
else if (DVInsn->getOperand(0).isFPImm())

View File

@ -254,6 +254,29 @@ unsigned FunctionLoweringInfo::CreateRegs(const Type *Ty) {
return FirstReg;
}
/// setByValArgumentFrameIndex - Record frame index for the byval
/// argument. This overrides previous frame index entry for this argument,
/// if any.
void FunctionLoweringInfo::setByValArgumentFrameIndex(const Argument *A,
int FI) {
assert (A->hasByValAttr() && "Argument does not have byval attribute!");
ByValArgFrameIndexMap[A] = FI;
}
/// getByValArgumentFrameIndex - Get frame index for the byval argument.
/// This routine must be used after the argument's frame index is set.
/// If the argument does not have any entry in the map then assertion
/// will be raised.
int FunctionLoweringInfo::getByValArgumentFrameIndex(const Argument *A) {
assert (A->hasByValAttr() && "Argument does not have byval attribute!");
DenseMap<const Argument *, int>::iterator I =
ByValArgFrameIndexMap.find(A);
assert (I != ByValArgFrameIndexMap.end() &&
"Argument does not have assigned frame index!");
return I->second;
}
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void llvm::AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI,

View File

@ -3917,7 +3917,8 @@ bool
SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
int64_t Offset,
const SDValue &N) {
if (!isa<Argument>(V))
const Argument *Arg = dyn_cast<Argument>(V);
if (!Arg)
return false;
MachineFunction &MF = DAG.getMachineFunction();
@ -3931,6 +3932,14 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
return false;
unsigned Reg = 0;
if (Arg->hasByValAttr()) {
// Byval arguments' frame index is recorded during argument lowering.
// Use this info directly.
const TargetRegisterInfo *TRI = DAG.getTarget().getRegisterInfo();
Reg = TRI->getFrameRegister(MF);
Offset = FuncInfo.getByValArgumentFrameIndex(Arg);
}
if (N.getNode() && N.getOpcode() == ISD::CopyFromReg) {
Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();
if (Reg && TargetRegisterInfo::isVirtualRegister(Reg)) {
@ -6131,6 +6140,12 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
i += NumParts;
}
// Note down frame index for byval arguments.
if (I->hasByValAttr() && !ArgValues.empty())
if (FrameIndexSDNode *FI =
dyn_cast<FrameIndexSDNode>(ArgValues[0].getNode()))
FuncInfo->setByValArgumentFrameIndex(I, FI->getIndex());
if (!I->use_empty()) {
SDValue Res;
if (!ArgValues.empty())

View File

@ -0,0 +1,53 @@
// This regression test checks byval arguments' debug info.
// Radar 8367011
// RUN: %llvmgcc -S -O0 -g %s -o - | \
// RUN: llc --disable-fp-elim -o %t.s -O0 -relocation-model=pic
// RUN: %compile_c %t.s -o %t.o
// RUN: %link %t.o -o %t.exe
// RUN: echo {break get\nrun\np missing_arg.b} > %t.in
// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \
// RUN: grep {1 = 4242}
// XTARGET: x86_64-apple-darwin
class EVT {
public:
int a;
int b;
int c;
};
class VAL {
public:
int x;
int y;
};
void foo(EVT e);
EVT bar();
void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) {
//CHECK: .ascii "missing_arg"
EVT e = bar();
if (dl == n)
foo(missing_arg);
}
EVT bar() {
EVT e;
return e;
}
void foo(EVT e) {}
int main(){
VAL v;
EVT ma;
ma.a = 1;
ma.b = 4242;
ma.c = 3;
int i = 42;
get (&i, 1, v, &v, 2, ma);
return 0;
}