Hi John,
On Thu, Nov 5, 2009 at 8:43 AM, John Criswell <criswell at uiuc.edu>
wrote:
> Does the debug facilities in LLVM TOT, at present, maintain information
> better than LLVM 2.6 (i.e., if a front-end puts the debug information in,
> will the optimizations not take it out)? Does the information that the
> llvm-gcc front-end adds comparable to what llvm-gcc in LLVM 2.6 does?
The FE has not changed significantly, other than bug fixes to improve
debug info.
> The problem that I'm having is that the SAFECode debug tool uses LLVM
debug
> information to print out nice error messages saying, "Your buffer
overflow
> is at line <x> in source file <file.c>." Before
transforms started removing
> debug information, my tool would print out source line/file info that was
> acceptably accurate. After the change, it started printing out horribly
> wrong information (e.g., giving the source and line number of some inlined
> function called by the function that actually generated the memory error).
This is because, while cloning function body during inlining, the
location information is also cloned, as expected. However, the inliner
should update location information to indicate that this instruction
is inlined at this location. I have local patch in my tree that is
waiting finishing touch in codegen before I commit. I pasted it below
for your reference.
Now, each instruction can have location information attached with it.
The location info (DILocation) include
- unsigned - line number
- unsigned - col number
- DIScope - lexical scope
- DILocation - inlined at location
When an instruction is inlined, the first three fields will stay
unchanged. But the inlined instruction will have non null "inlined at
location" indicating where this instruction was inlined.
-
Devang
Index: Utils/CloneFunction.cpp
==================================================================---
Utils/CloneFunction.cpp (revision 86036)
+++ Utils/CloneFunction.cpp (working copy)
@@ -20,6 +20,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Analysis/ConstantFolding.h"
@@ -349,6 +350,27 @@
Ops.size(), Context, TD);
}
+static MDNode *UpdateInlinedAtInfo(MDNode *InsnMD, MDNode *TheCallMD,
+ LLVMContext &Context) {
+ DILocation ILoc(InsnMD);
+ if (ILoc.isNull()) return InsnMD;
+
+ DILocation CallLoc(TheCallMD);
+ if (CallLoc.isNull()) return InsnMD;
+
+ DILocation OrigLocation = ILoc.getOrigLocation();
+ MDNode *NewLoc = TheCallMD;
+ if (!OrigLocation.isNull())
+ NewLoc = UpdateInlinedAtInfo(OrigLocation.getNode(), TheCallMD, Context);
+
+ SmallVector<Value *, 4> MDVs;
+ MDVs.push_back(InsnMD->getElement(0)); // Line
+ MDVs.push_back(InsnMD->getElement(1)); // Col
+ MDVs.push_back(InsnMD->getElement(2)); // Scope
+ MDVs.push_back(NewLoc);
+ return MDNode::get(Context, MDVs.data(), MDVs.size());
+}
+
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
/// except that it does some simple constant prop and DCE on the fly. The
/// effect of this is to copy significantly less code in cases where (for
@@ -361,7 +383,8 @@
SmallVectorImpl<ReturnInst*>
&Returns,
const char *NameSuffix,
ClonedCodeInfo *CodeInfo,
- const TargetData *TD) {
+ const TargetData *TD,
+ Instruction *TheCall) {
assert(NameSuffix && "NameSuffix cannot be null!");
#ifndef NDEBUG
@@ -411,8 +434,22 @@
}
// Otherwise, remap the rest of the instructions normally.
- for (; I != NewBB->end(); ++I)
+ unsigned DbgKind = 0;
+ MDNode *TheCallMD = NULL;
+ SmallVector<Value *, 4> MDVs;
+ LLVMContext &Context = OldFunc->getContext();
+ if (TheCall && TheCall->hasMetadata()) {
+ DbgKind = Context.getMetadata().getMDKind("dbg");
+ TheCallMD = Context.getMetadata().getMD(DbgKind, TheCall);
+ }
+ for (; I != NewBB->end(); ++I) {
+ if (TheCallMD && I->hasMetadata())
+ if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) {
+ MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context);
+ Context.getMetadata().addMD(DbgKind, NewMD, I);
+ }
RemapInstruction(I, ValueMap);
+ }
}
// Defer PHI resolution until rest of function is resolved, PHI resolution
Index: Utils/InlineFunction.cpp
==================================================================---
Utils/InlineFunction.cpp (revision 86036)
+++ Utils/InlineFunction.cpp (working copy)
@@ -386,7 +386,7 @@
// (which can happen, e.g., because an argument was constant), but
we'll be
// happy with whatever the cloner can do.
CloneAndPruneFunctionInto(Caller, CalledFunc, ValueMap, Returns,
".i",
- &InlinedFunctionInfo, TD);
+ &InlinedFunctionInfo, TD, TheCall);
// Remember the first block that is newly cloned over.
FirstNewBlock = LastBlock; ++FirstNewBlock;