Fix bug so that programIndex (et al.) are available in the debugger.

It's now possible to successfully print out the value of programIndex,
programCount, etc., in the debugger.  The issue was that they were
defined as having InternalLinkage, which meant that DCE removed them
at the end of compilation.  Now they're declared to have WeakODRLinkage,
which ensures that one copy survives (but there aren't multiply-defined
symbols when compiling multiple files.)
This commit is contained in:
Matt Pharr
2012-04-28 13:47:31 -10:00
parent 27b62781cc
commit a1a43cdfe0
3 changed files with 49 additions and 36 deletions

View File

@@ -637,16 +637,36 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
static void static void
lDefineConstantInt(const char *name, int val, llvm::Module *module, lDefineConstantInt(const char *name, int val, llvm::Module *module,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
Symbol *pw = Symbol *sym =
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(), new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
SC_STATIC); SC_STATIC);
pw->constValue = new ConstExpr(pw->type, val, SourcePos()); sym->constValue = new ConstExpr(sym->type, val, SourcePos());
llvm::Type *ltype = LLVMTypes::Int32Type; llvm::Type *ltype = LLVMTypes::Int32Type;
llvm::Constant *linit = LLVMInt32(val); llvm::Constant *linit = LLVMInt32(val);
pw->storagePtr = new llvm::GlobalVariable(*module, ltype, true, // Use WeakODRLinkage rather than InternalLinkage so that a definition
llvm::GlobalValue::InternalLinkage, // survives even if it's not used in the module, so that the symbol is
linit, pw->name.c_str()); // there in the debugger.
symbolTable->AddVariable(pw); sym->storagePtr = new llvm::GlobalVariable(*module, ltype, true,
llvm::GlobalValue::WeakODRLinkage,
linit, name);
symbolTable->AddVariable(sym);
if (m->diBuilder != NULL) {
llvm::DIFile file;
llvm::DIType diType = sym->type->GetDIType(file);
Assert(diType.Verify());
// FIXME? DWARF says that this (and programIndex below) should
// have the DW_AT_artifical attribute. It's not clear if this
// matters for anything though.
llvm::DIGlobalVariable var =
m->diBuilder->createGlobalVariable(name,
file,
0 /* line */,
diType,
true /* static */,
sym->storagePtr);
Assert(var.Verify());
}
} }
@@ -672,21 +692,37 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
static void static void
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) { lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
Symbol *pidx = Symbol *sym =
new Symbol("programIndex", SourcePos(), new Symbol("programIndex", SourcePos(),
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC); AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
int pi[ISPC_MAX_NVEC]; int pi[ISPC_MAX_NVEC];
for (int i = 0; i < g->target.vectorWidth; ++i) for (int i = 0; i < g->target.vectorWidth; ++i)
pi[i] = i; pi[i] = i;
pidx->constValue = new ConstExpr(pidx->type, pi, SourcePos()); sym->constValue = new ConstExpr(sym->type, pi, SourcePos());
llvm::Type *ltype = LLVMTypes::Int32VectorType; llvm::Type *ltype = LLVMTypes::Int32VectorType;
llvm::Constant *linit = LLVMInt32Vector(pi); llvm::Constant *linit = LLVMInt32Vector(pi);
pidx->storagePtr = new llvm::GlobalVariable(*module, ltype, true, // See comment in lDefineConstantInt() for why WeakODRLinkage is used here
llvm::GlobalValue::InternalLinkage, linit, sym->storagePtr = new llvm::GlobalVariable(*module, ltype, true,
pidx->name.c_str()); llvm::GlobalValue::WeakODRLinkage,
symbolTable->AddVariable(pidx); linit,
sym->name.c_str());
symbolTable->AddVariable(sym);
if (m->diBuilder != NULL) {
llvm::DIFile file;
llvm::DIType diType = sym->type->GetDIType(file);
Assert(diType.Verify());
llvm::DIGlobalVariable var =
m->diBuilder->createGlobalVariable(sym->name.c_str(),
file,
0 /* line */,
diType,
false /* static */,
sym->storagePtr);
Assert(var.Verify());
}
} }

23
ctx.cpp
View File

@@ -339,29 +339,6 @@ FunctionEmitContext::FunctionEmitContext(Function *func, Symbol *funSym,
/* And start a scope representing the initial function scope */ /* And start a scope representing the initial function scope */
StartScope(); StartScope();
llvm::DIFile file = funcStartPos.GetDIFile();
Symbol *programIndexSymbol = m->symbolTable->LookupVariable("programIndex");
Assert(programIndexSymbol && programIndexSymbol->storagePtr);
llvm::DIGlobalVariable var =
m->diBuilder->createGlobalVariable(programIndexSymbol->name,
file,
funcStartPos.first_line,
programIndexSymbol->type->GetDIType(file),
true /* static */,
programIndexSymbol->storagePtr);
Assert(var.Verify());
Symbol *programCountSymbol = m->symbolTable->LookupVariable("programCount");
Assert(programCountSymbol);
var =
m->diBuilder->createGlobalVariable(programCountSymbol->name,
file,
funcStartPos.first_line,
programCountSymbol->type->GetDIType(file),
true /* static */,
programCountSymbol->storagePtr);
Assert(var.Verify());
} }
} }

View File

@@ -198,7 +198,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
// value // value
maskSymbol->storagePtr = ctx->GetFullMaskPointer(); maskSymbol->storagePtr = ctx->GetFullMaskPointer();
// add debugging info for __mask, programIndex, ... // add debugging info for __mask
maskSymbol->pos = firstStmtPos; maskSymbol->pos = firstStmtPos;
ctx->EmitVariableDebugInfo(maskSymbol); ctx->EmitVariableDebugInfo(maskSymbol);