Upgrade to LLVM-2.9. Thanks to David Nadlinger for the patch.

This commit is contained in:
Kelly Wilson 2011-04-19 21:57:15 -06:00
parent 3bfc0a04d8
commit b26b0f4196
15 changed files with 221 additions and 250 deletions

View file

@ -3,7 +3,7 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include "llvm/System/Path.h" #include "llvm/Support/Path.h"
#include "libconfig.h++" #include "libconfig.h++"

View file

@ -57,7 +57,7 @@ IRTargetScope::IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, l
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
IRState::IRState(llvm::Module* m) IRState::IRState(llvm::Module* m)
: module(m), difactory(*m) : module(m), dibuilder(*m)
{ {
interfaceInfoType = NULL; interfaceInfoType = NULL;
mutexType = NULL; mutexType = NULL;

View file

@ -13,6 +13,7 @@
#include "ir/irstruct.h" #include "ir/irstruct.h"
#include "ir/irvar.h" #include "ir/irvar.h"
#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Support/CallSite.h" #include "llvm/Support/CallSite.h"
namespace llvm { namespace llvm {
@ -157,7 +158,7 @@ struct IRState
IRBuilderHelper ir; IRBuilderHelper ir;
// debug info helper // debug info helper
llvm::DIFactory difactory; llvm::DIBuilder dibuilder;
// static ctors/dtors/unittests // static ctors/dtors/unittests
typedef std::list<FuncDeclaration*> FuncDeclList; typedef std::list<FuncDeclaration*> FuncDeclList;

View file

@ -1,7 +1,7 @@
#include "gen/linker.h" #include "gen/linker.h"
#include "gen/llvm.h" #include "gen/llvm.h"
#include "llvm/Linker.h" #include "llvm/Linker.h"
#include "llvm/System/Program.h" #include "llvm/Support/Program.h"
#if _WIN32 #if _WIN32
#include "llvm/Support/SystemUtils.h" #include "llvm/Support/SystemUtils.h"
#endif #endif

View file

@ -7,7 +7,6 @@
#include "llvm/LinkAllVMCore.h" #include "llvm/LinkAllVMCore.h"
#include "llvm/Linker.h" #include "llvm/Linker.h"
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
@ -160,15 +159,6 @@ int main(int argc, char** argv)
VersionCondition::addPredefinedGlobalIdent("D_Version2"); VersionCondition::addPredefinedGlobalIdent("D_Version2");
#endif #endif
// merge DFLAGS environment variable into argc/argv
getenv_setargv("DFLAGS", &argc, &argv);
#if 0
for (int i = 0; i < argc; i++)
{
printf("argv[%d] = '%s'\n", i, argv[i]);
}
#endif
// build complete fixed up list of command line arguments // build complete fixed up list of command line arguments
std::vector<const char*> final_args; std::vector<const char*> final_args;
final_args.reserve(argc); final_args.reserve(argc);

View file

@ -7,6 +7,7 @@
#include "gen/tollvm.h" #include "gen/tollvm.h"
#include "gen/functions.h" #include "gen/functions.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
namespace cl = llvm::cl; namespace cl = llvm::cl;
@ -437,7 +438,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
assert(vd->ir.irLocal->value); assert(vd->ir.irLocal->value);
LLValue* value = vd->ir.irLocal->value; LLValue* value = vd->ir.irLocal->value;
const LLType* type = value->getType(); const LLType* type = value->getType();
if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject())) if (llvm::isa<llvm::AllocaInst>(llvm::GetUnderlyingObject(value)))
// This will be copied to the nesting frame. // This will be copied to the nesting frame.
type = type->getContainedType(0); type = type->getContainedType(0);
types.push_back(type); types.push_back(type);
@ -631,7 +632,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
Logger::println("nested param: %s", vd->toChars()); Logger::println("nested param: %s", vd->toChars());
LOG_SCOPE LOG_SCOPE
LLValue* value = vd->ir.irLocal->value; LLValue* value = vd->ir.irLocal->value;
if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject())) { if (llvm::isa<llvm::AllocaInst>(llvm::GetUnderlyingObject(value))) {
Logger::println("Copying to nested frame"); Logger::println("Copying to nested frame");
// The parameter value is an alloca'd stack slot. // The parameter value is an alloca'd stack slot.
// Copy to the nesting frame and leave the alloca for // Copy to the nesting frame and leave the alloca for

View file

@ -183,7 +183,6 @@ static void addPassesForOptLevel(PassManager& pm) {
addPass(pm, createLoopRotatePass()); addPass(pm, createLoopRotatePass());
addPass(pm, createLICMPass()); addPass(pm, createLICMPass());
addPass(pm, createLoopUnswitchPass()); addPass(pm, createLoopUnswitchPass());
addPass(pm, createLoopIndexSplitPass());
addPass(pm, createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
addPass(pm, createIndVarSimplifyPass()); addPass(pm, createIndVarSimplifyPass());
addPass(pm, createLoopDeletionPass()); addPass(pm, createLoopDeletionPass());

View file

@ -1,7 +1,7 @@
#include "gen/programs.h" #include "gen/programs.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/System/Program.h" #include "llvm/Support/Program.h"
#include "root.h" // error(char*) #include "root.h" // error(char*)
#include "mars.h" // fatal() #include "mars.h" // fatal()

View file

@ -1,7 +1,7 @@
#ifndef LDC_GEN_PROGRAMS_H #ifndef LDC_GEN_PROGRAMS_H
#define LDC_GEN_PROGRAMS_H #define LDC_GEN_PROGRAMS_H
#include "llvm/System/Path.h" #include "llvm/Support/Path.h"
llvm::sys::Path getGcc(); llvm::sys::Path getGcc();

View file

@ -1,7 +1,8 @@
#include "gen/llvm.h" #include "gen/llvm.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/System/Path.h" #include "llvm/Support/Dwarf.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/PathV2.h"
#include "declaration.h" #include "declaration.h"
#include "module.h" #include "module.h"
@ -43,22 +44,25 @@ static Module* getDefinedModule(Dsymbol* s)
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name); static llvm::DIType dwarfTypeDescription_impl(Type* type, const char* c_name);
static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name); static llvm::DIType dwarfTypeDescription(Type* type, const char* c_name);
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
llvm::DIFile DtoDwarfFile(Loc loc, llvm::DICompileUnit compileUnit) llvm::DIFile DtoDwarfFile(Loc loc)
{ {
typedef llvm::sys::Path LLPath; llvm::SmallString<128> path(loc.filename);
LLPath path = loc.filename ? LLPath(loc.filename) : LLPath(); llvm::sys::fs::make_absolute(path);
path.makeAbsolute();
return gIR->difactory.CreateFile(path.getLast(), path.getDirname(), compileUnit); return gIR->dibuilder.createFile(
llvm::sys::path::filename(path),
llvm::sys::path::parent_path(path)
);
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileUnit) static llvm::DIType dwarfBasicType(Type* type)
{ {
Type* t = type->toBasetype(); Type* t = type->toBasetype();
const LLType* T = DtoType(type); const LLType* T = DtoType(type);
@ -81,67 +85,52 @@ static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileU
assert(0 && "unsupported basictype for debug info"); assert(0 && "unsupported basictype for debug info");
} }
return gIR->difactory.CreateBasicType( return gIR->dibuilder.createBasicType(
compileUnit, // context
type->toChars(), // name type->toChars(), // name
DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)), // file
0, // line number
getTypeBitSize(T), // size (bits) getTypeBitSize(T), // size (bits)
getABITypeAlign(T)*8, // align (bits) getABITypeAlign(T)*8, // align (bits)
0, // offset (bits) id
//FIXME: need flags?
0, // flags
id // encoding
); );
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIDerivedType dwarfDerivedType(Type* type, llvm::DICompileUnit compileUnit) static llvm::DIType dwarfPointerType(Type* type)
{ {
const LLType* T = DtoType(type); const LLType* T = DtoType(type);
Type* t = type->toBasetype(); Type* t = type->toBasetype();
assert(t->ty == Tpointer && "unsupported derivedtype for debug info, only pointers allowed"); assert(t->ty == Tpointer && "only pointers allowed for debug info in dwarfPointerType");
// find base type // find base type
llvm::DIType basetype; llvm::DIType basetype;
Type* nt = t->nextOf(); Type* nt = t->nextOf();
basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL); basetype = dwarfTypeDescription_impl(nt, NULL);
if (nt->ty == Tvoid) if (nt->ty == Tvoid)
basetype = llvm::DIType(NULL); basetype = llvm::DIType(NULL);
return gIR->difactory.CreateDerivedType( return gIR->dibuilder.createPointerType(
DW_TAG_pointer_type, // tag basetype,
compileUnit, // context
type->toChars(), // name
DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)), // file
0, // line number
getTypeBitSize(T), // size (bits) getTypeBitSize(T), // size (bits)
getABITypeAlign(T)*8, // align (bits) getABITypeAlign(T)*8, // align (bits)
0, // offset (bits) type->toChars() // name
//FIXME: need flags?
0, // flags
basetype // derived from
); );
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIDerivedType dwarfMemberType(unsigned linnum, Type* type, llvm::DICompileUnit compileUnit, llvm::DIFile file, const char* c_name, unsigned offset) static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile file, const char* c_name, unsigned offset)
{ {
const LLType* T = DtoType(type); const LLType* T = DtoType(type);
Type* t = type->toBasetype(); Type* t = type->toBasetype();
// find base type // find base type
llvm::DIType basetype; llvm::DIType basetype;
basetype = dwarfTypeDescription(t, compileUnit, NULL); basetype = dwarfTypeDescription(t, NULL);
if (t->ty == Tvoid) if (t->ty == Tvoid)
basetype = llvm::DIType(NULL); basetype = llvm::DIType(NULL);
return gIR->difactory.CreateDerivedType( return gIR->dibuilder.createMemberType(
DW_TAG_member, // tag
compileUnit, // context
c_name, // name c_name, // name
file, // file file, // file
linnum, // line number linnum, // line number
@ -158,13 +147,12 @@ static llvm::DIDerivedType dwarfMemberType(unsigned linnum, Type* type, llvm::DI
static void add_base_fields( static void add_base_fields(
ClassDeclaration* sd, ClassDeclaration* sd,
llvm::DICompileUnit compileUnit,
llvm::DIFile file, llvm::DIFile file,
std::vector<llvm::DIDescriptor>& elems) std::vector<llvm::Value*>& elems)
{ {
if (sd->baseClass) if (sd->baseClass)
{ {
add_base_fields(sd->baseClass, compileUnit, file, elems); add_base_fields(sd->baseClass, file, elems);
} }
ArrayIter<VarDeclaration> it(sd->fields); ArrayIter<VarDeclaration> it(sd->fields);
@ -173,15 +161,12 @@ static void add_base_fields(
for (; !it.done(); it.next()) for (; !it.done(); it.next())
{ {
VarDeclaration* vd = it.get(); VarDeclaration* vd = it.get();
elems.push_back(dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, file, vd->toChars(), vd->offset)); elems.push_back(dwarfMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset));
} }
} }
static llvm::DIType dwarfCompositeType(Type* type)
//FIXME: This does not use llvm's DIFactory as it can't
// handle recursive types properly.
static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit compileUnit)
{ {
const LLType* T = DtoType(type); const LLType* T = DtoType(type);
Type* t = type->toBasetype(); Type* t = type->toBasetype();
@ -191,121 +176,126 @@ static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit
unsigned linnum = 0; unsigned linnum = 0;
llvm::DIFile file; llvm::DIFile file;
// prepare tag and members
unsigned tag;
// elements // elements
std::vector<llvm::DIDescriptor> elems; std::vector<llvm::Value*> elems;
// pointer to ir->diCompositeType // pointer to ir->diCompositeType
llvm::DICompositeType *diCompositeType = 0; llvm::DIType *diCompositeType = 0;
llvm::DICompositeType derivedFrom; llvm::DIType derivedFrom;
// dynamic array assert((t->ty == Tstruct || t->ty == Tclass) &&
if (t->ty == Tarray) "unsupported type for dwarfCompositeType");
AggregateDeclaration* sd;
if (t->ty == Tstruct)
{ {
file = DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)); TypeStruct* ts = (TypeStruct*)t;
tag = DW_TAG_structure_type; sd = ts->sym;
elems.push_back(dwarfMemberType(0, Type::tsize_t, compileUnit, file, "length", 0)); }
elems.push_back(dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, file, "ptr", global.params.is64bit?8:4)); else
{
TypeClass* tc = (TypeClass*)t;
sd = tc->sym;
}
assert(sd);
// make sure it's resolved
sd->codegen(Type::sir);
// if we don't know the aggregate's size, we don't know enough about it
// to provide debug info. probably a forward-declared struct?
if (sd->sizeok == 0)
return llvm::DICompositeType(NULL);
IrStruct* ir = sd->ir.irStruct;
assert(ir);
if ((llvm::MDNode*)ir->diCompositeType != 0)
return ir->diCompositeType;
diCompositeType = &ir->diCompositeType;
name = sd->toChars();
linnum = sd->loc.linnum;
file = DtoDwarfFile(sd->loc);
// set diCompositeType to handle recursive types properly
if (t->ty == Tclass) {
ir->diCompositeType = gIR->dibuilder.createClassType(
llvm::DIDescriptor(file),
name, // name
file, // compile unit where defined
linnum, // line number where defined
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
0, // offset in bits,
llvm::DIType::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
llvm::DIArray(0)
);
} else {
ir->diCompositeType = gIR->dibuilder.createStructType(
llvm::DIDescriptor(file),
name, // name
file, // compile unit where defined
linnum, // line number where defined
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
llvm::DIType::FlagFwdDecl, // flags
llvm::DIArray(0)
);
} }
// struct/class if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
else if (t->ty == Tstruct || t->ty == Tclass)
{ {
AggregateDeclaration* sd;
if (t->ty == Tstruct) if (t->ty == Tstruct)
{ {
TypeStruct* ts = (TypeStruct*)t; ArrayIter<VarDeclaration> it(sd->fields);
sd = ts->sym; size_t narr = sd->fields.dim;
tag = DW_TAG_structure_type; elems.reserve(narr);
for (; !it.done(); it.next())
{
VarDeclaration* vd = it.get();
llvm::DIType dt = dwarfMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset);
elems.push_back(dt);
}
} }
else else
{ {
TypeClass* tc = (TypeClass*)t; ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration();
sd = tc->sym; add_base_fields(classDecl, file, elems);
tag = DW_TAG_class_type; if (classDecl->baseClass)
derivedFrom = dwarfCompositeType(classDecl->baseClass->getType());
} }
assert(sd);
// make sure it's resolved
sd->codegen(Type::sir);
// if we don't know the aggregate's size, we don't know enough about it
// to provide debug info. probably a forward-declared struct?
if (sd->sizeok == 0)
return llvm::DICompositeType(NULL);
IrStruct* ir = sd->ir.irStruct;
assert(ir);
if ((llvm::MDNode*)ir->diCompositeType != 0)
return ir->diCompositeType;
diCompositeType = &ir->diCompositeType;
name = sd->toChars();
linnum = sd->loc.linnum;
file = DtoDwarfFile(sd->loc, DtoDwarfCompileUnit(getDefinedModule(sd)));
// set diCompositeType to handle recursive types properly
ir->diCompositeType = gIR->difactory.CreateCompositeTypeEx(
tag, // tag
compileUnit, // context
name, // name
file, // compile unit where defined
linnum, // line number where defined
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getTypeBitSize(T), false), // size in bits
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getABITypeAlign(T)*8, false), // alignment in bits
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 0, false), // offset in bits,
llvm::DIType::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
llvm::DIArray(0)
);
if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
{
if (t->ty == Tstruct)
{
ArrayIter<VarDeclaration> it(sd->fields);
size_t narr = sd->fields.dim;
elems.reserve(narr);
for (; !it.done(); it.next())
{
VarDeclaration* vd = it.get();
llvm::DIDerivedType dt = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, file, vd->toChars(), vd->offset);
elems.push_back(dt);
}
}
else
{
ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration();
add_base_fields(classDecl, compileUnit, file, elems);
if (classDecl->baseClass)
derivedFrom = dwarfCompositeType(classDecl->baseClass->getType(), compileUnit);
}
}
}
// unsupported composite type
else
{
assert(0 && "unsupported compositetype for debug info");
} }
llvm::DIArray elemsArray = llvm::DIArray elemsArray =
gIR->difactory.GetOrCreateArray(elems.data(), elems.size()); gIR->dibuilder.getOrCreateArray(elems.data(), elems.size());
llvm::DIType ret;
if (t->ty == Tclass) {
ret = gIR->dibuilder.createClassType(
llvm::DIDescriptor(file),
name, // name
file, // compile unit where defined
linnum, // line number where defined
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
0, // offset in bits,
llvm::DIType::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
elemsArray
);
} else {
ret = gIR->dibuilder.createStructType(
llvm::DIDescriptor(file),
name, // name
file, // compile unit where defined
linnum, // line number where defined
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
llvm::DIType::FlagFwdDecl, // flags
elemsArray
);
}
llvm::DICompositeType ret = gIR->difactory.CreateCompositeTypeEx(
tag, // tag
compileUnit, // context
name, // name
file, // compile unit where defined
linnum, // line number where defined
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getTypeBitSize(T), false), // size in bits
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getABITypeAlign(T)*8, false), // alignment in bits
LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 0, false), // offset in bits,
llvm::DIType::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
elemsArray);
if (diCompositeType) if (diCompositeType)
*diCompositeType = ret; *diCompositeType = ret;
return ret; return ret;
@ -320,77 +310,79 @@ static llvm::DIGlobalVariable dwarfGlobalVariable(LLGlobalVariable* ll, VarDecla
#else #else
assert(vd->isDataseg()); assert(vd->isDataseg());
#endif #endif
llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
return gIR->difactory.CreateGlobalVariable( return gIR->dibuilder.createGlobalVariable(
compileUnit, // context vd->toChars(), // name TODO: mangle() or toPrettyChars() instead?
vd->mangle(), // name DtoDwarfFile(vd->loc), // file
vd->toPrettyChars(), // displayname
vd->toChars(), // linkage name
DtoDwarfFile(vd->loc, DtoDwarfCompileUnit(getDefinedModule(vd))), // file
vd->loc.linnum, // line num vd->loc.linnum, // line num
dwarfTypeDescription_impl(vd->type, compileUnit, NULL), // type dwarfTypeDescription_impl(vd->type, NULL), // type
vd->protection == PROTprivate, // is local to unit vd->protection == PROTprivate, // is local to unit
true, // is definition
ll // value ll // value
); );
} }
//////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type)
{
assert(!vd->isDataseg() && "static variable");
unsigned tag;
if (vd->isParameter())
tag = DW_TAG_arg_variable;
else
tag = DW_TAG_auto_variable;
return gIR->difactory.CreateVariable(
tag, // tag
gIR->func()->diSubprogram, // context
vd->toChars(), // name
DtoDwarfFile(vd->loc, DtoDwarfCompileUnit(getDefinedModule(vd))), // file
vd->loc.linnum, // line num
type, // type
true // preserve
);
}
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static void dwarfDeclare(LLValue* var, llvm::DIVariable divar) static void dwarfDeclare(LLValue* var, llvm::DIVariable divar)
{ {
llvm::Instruction *instr = gIR->difactory.InsertDeclare(var, divar, gIR->scopebb()); llvm::Instruction *instr = gIR->dibuilder.insertDeclare(var, divar, gIR->scopebb());
instr->setDebugLoc(gIR->ir->getCurrentDebugLocation()); instr->setDebugLoc(gIR->ir->getCurrentDebugLocation());
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name)
llvm::DIType dwarfArrayType(Type* type) {
const LLType* T = DtoType(type);
Type* t = type->toBasetype();
llvm::DIFile file = DtoDwarfFile(Loc(gIR->dmodule, 0));
std::vector<llvm::Value*> elems;
elems.push_back(dwarfMemberType(0, Type::tsize_t, file, "length", 0));
elems.push_back(dwarfMemberType(0, t->nextOf()->pointerTo(), file, "ptr", global.params.is64bit?8:4));
return gIR->dibuilder.createStructType
(
llvm::DIDescriptor(file),
llvm::StringRef(), // Name TODO: Really no name for arrays?
file, // File
0, // LineNo
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
0, // What here?
gIR->dibuilder.getOrCreateArray(elems.data(), elems.size())
);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::DIType dwarfTypeDescription_impl(Type* type, const char* c_name)
{ {
Type* t = type->toBasetype(); Type* t = type->toBasetype();
if (t->ty == Tvoid) if (t->ty == Tvoid)
return llvm::DIType(NULL); return llvm::DIType(NULL);
else if (t->isintegral() || t->isfloating()) else if (t->isintegral() || t->isfloating())
return dwarfBasicType(type, cu); return dwarfBasicType(type);
else if (t->ty == Tpointer) else if (t->ty == Tpointer)
return dwarfDerivedType(type, cu); return dwarfPointerType(type);
else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass) else if (t->ty == Tarray)
return dwarfCompositeType(type, cu); return dwarfArrayType(type);
else if (t->ty == Tstruct || t->ty == Tclass)
return dwarfCompositeType(type);
return llvm::DIType(NULL); return llvm::DIType(NULL);
} }
static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name) static llvm::DIType dwarfTypeDescription(Type* type, const char* c_name)
{ {
Type* t = type->toBasetype(); Type* t = type->toBasetype();
if (t->ty == Tclass) if (t->ty == Tclass)
return dwarfTypeDescription_impl(type->pointerTo(), cu, c_name); return dwarfTypeDescription_impl(type->pointerTo(), c_name);
else else
return dwarfTypeDescription_impl(type, cu, c_name); return dwarfTypeDescription_impl(type, c_name);
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
@ -400,17 +392,29 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
Logger::println("D to dwarf local variable"); Logger::println("D to dwarf local variable");
LOG_SCOPE; LOG_SCOPE;
// get compile units
llvm::DICompileUnit thisCU = DtoDwarfCompileUnit(gIR->dmodule);
llvm::DICompileUnit varCU = DtoDwarfCompileUnit(getDefinedModule(vd));
// get type description // get type description
llvm::DIType TD = dwarfTypeDescription(vd->type, thisCU, NULL); llvm::DIType TD = dwarfTypeDescription(vd->type, NULL);
if ((llvm::MDNode*)TD == 0) if ((llvm::MDNode*)TD == 0)
return; // unsupported return; // unsupported
// get variable description // get variable description
vd->debugVariable = dwarfVariable(vd, TD); assert(!vd->isDataseg() && "static variable");
unsigned tag;
if (vd->isParameter())
tag = DW_TAG_arg_variable;
else
tag = DW_TAG_auto_variable;
vd->debugVariable = gIR->dibuilder.createLocalVariable(
tag, // tag
gIR->func()->diSubprogram, // context
vd->toChars(), // name
DtoDwarfFile(vd->loc), // file
vd->loc.linnum, // line num
TD, // type
true // preserve
);
// declare // declare
dwarfDeclare(ll, vd->debugVariable); dwarfDeclare(ll, vd->debugVariable);
@ -418,23 +422,11 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) void DtoDwarfCompileUnit(Module* m)
{ {
Logger::println("D to dwarf compile_unit"); Logger::println("D to dwarf compile_unit");
LOG_SCOPE; LOG_SCOPE;
static bool mainUnitCreated = false;
// we might be generating for an import
IrModule* irmod = getIrModule(m);
if ((llvm::MDNode*)irmod->diCompileUnit != 0)
{
//assert (irmod->diCompileUnit.getGV()->getParent() == gIR->module
// && "debug info compile unit belongs to incorrect llvm module!");
return irmod->diCompileUnit;
}
// prepare srcpath // prepare srcpath
std::string srcpath(FileName::path(m->srcfile->name->toChars())); std::string srcpath(FileName::path(m->srcfile->name->toChars()));
if (!FileName::absolute(srcpath.c_str())) { if (!FileName::absolute(srcpath.c_str())) {
@ -445,20 +437,15 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
srcpath = srcpath + '/'; srcpath = srcpath + '/';
} }
bool isMain = !mainUnitCreated && gIR->dmodule == m; gIR->dibuilder.createCompileUnit(
// make compile unit
irmod->diCompileUnit = gIR->difactory.CreateCompileUnit(
global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D, global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D,
m->srcfile->name->toChars(), m->srcfile->name->toChars(),
srcpath, srcpath,
"LDC (http://www.dsource.org/projects/ldc)", "LDC (http://www.dsource.org/projects/ldc)",
isMain, // isMain, false, // isOptimized TODO
false // isOptimized llvm::StringRef(), // Flags TODO
1 // Runtime Version TODO
); );
if (isMain)
mainUnitCreated = true;
return irmod->diCompileUnit;
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
@ -468,24 +455,20 @@ llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd)
Logger::println("D to dwarf subprogram"); Logger::println("D to dwarf subprogram");
LOG_SCOPE; LOG_SCOPE;
llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); llvm::DIFile file = DtoDwarfFile(fd->loc);
llvm::DIFile file = DtoDwarfFile(fd->loc, DtoDwarfCompileUnit(getDefinedModule(fd)));
Type *retType = ((TypeFunction*)fd->type)->next; Type *retType = ((TypeFunction*)fd->type)->next;
// FIXME: duplicates ? // FIXME: duplicates ?
return gIR->difactory.CreateSubprogram( return gIR->dibuilder.createFunction(
context, // context llvm::DICompileUnit(file), // context
fd->toPrettyChars(), // name fd->toPrettyChars(), // name
fd->toPrettyChars(), // display name
fd->mangle(), // linkage name fd->mangle(), // linkage name
file, // file file, // file
fd->loc.linnum, // line no fd->loc.linnum, // line no
dwarfTypeDescription(retType, context, NULL), // type dwarfTypeDescription(retType, NULL), // type
fd->protection == PROTprivate, // is local to unit fd->protection == PROTprivate, // is local to unit
gIR->dmodule == getDefinedModule(fd), // isdefinition gIR->dmodule == getDefinedModule(fd), // isdefinition
0, 0, // VK, Index 0, // Flags
llvm::DIType(),
false, // isArtificial
false, // isOptimized false, // isOptimized
fd->ir.irFunc->func fd->ir.irFunc->func
); );
@ -498,15 +481,14 @@ llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char
Logger::println("D to dwarf subprogram"); Logger::println("D to dwarf subprogram");
LOG_SCOPE; LOG_SCOPE;
llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); llvm::DIFile file(DtoDwarfFile(Loc(gIR->dmodule, 0)));
// FIXME: duplicates ? // FIXME: duplicates ?
return gIR->difactory.CreateSubprogram( return gIR->dibuilder.createFunction(
context, // context llvm::DIDescriptor(file), // context
prettyname, // name prettyname, // name
prettyname, // display name
mangledname, // linkage name mangledname, // linkage name
DtoDwarfFile(Loc(gIR->dmodule, 0), context), // compile unit file, // file
0, // line no 0, // line no
llvm::DIType(NULL), // return type. TODO: fill it up llvm::DIType(NULL), // return type. TODO: fill it up
true, // is local to unit true, // is local to unit
@ -568,7 +550,7 @@ void DtoDwarfValue(LLValue* var, VarDeclaration* vd)
if (llvm::isa<llvm::AllocaInst>(vd->ir.irLocal->value) == 0) if (llvm::isa<llvm::AllocaInst>(vd->ir.irLocal->value) == 0)
return; return;
llvm::Instruction *instr = gIR->difactory.InsertDbgValueIntrinsic(vd->ir.irLocal->value, 0, vd->debugVariable, gIR->scopebb()); llvm::Instruction *instr = gIR->dibuilder.insertDbgValueIntrinsic(vd->ir.irLocal->value, 0, vd->debugVariable, gIR->scopebb());
instr->setDebugLoc(gIR->ir->getCurrentDebugLocation()); instr->setDebugLoc(gIR->ir->getCurrentDebugLocation());
} }

View file

@ -8,9 +8,8 @@ void RegisterDwarfSymbols(llvm::Module* mod);
/** /**
* Emit the Dwarf compile_unit global for a Module m. * Emit the Dwarf compile_unit global for a Module m.
* @param m * @param m
* @return the Dwarf compile_unit.
*/ */
llvm::DICompileUnit DtoDwarfCompileUnit(Module* m); void DtoDwarfCompileUnit(Module* m);
/** /**
* Emit the Dwarf subprogram global for a function declaration fd. * Emit the Dwarf subprogram global for a function declaration fd.

View file

@ -16,7 +16,7 @@
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/LinkAllPasses.h" #include "llvm/LinkAllPasses.h"
#include "llvm/System/Program.h" #include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h" #include "llvm/Support/FormattedStream.h"
@ -200,7 +200,7 @@ void writeModule(llvm::Module* m, std::string filename)
LOG_SCOPE; LOG_SCOPE;
if (llvm::verifyModule(*m,llvm::ReturnStatusAction,&verifyErr)) if (llvm::verifyModule(*m,llvm::ReturnStatusAction,&verifyErr))
{ {
//error("%s", verifyErr.c_str()); error("%s", verifyErr.c_str());
fatal(); fatal();
} }
else { else {

View file

@ -19,14 +19,14 @@ struct ArrayIter
ArrayIter<C>& operator=(const Array& arr) ArrayIter<C>& operator=(const Array& arr)
{ {
array = &arr; array = const_cast<Array*>(&arr);
index = 0; index = 0;
return *this; return *this;
} }
ArrayIter<C>& operator=(const Array* arr) ArrayIter<C>& operator=(const Array* arr)
{ {
assert(arr && "null array"); assert(arr && "null array");
array = arr; array = const_cast<Array*>(arr);
index = 0; index = 0;
return *this; return *this;
} }

View file

@ -13,7 +13,6 @@ struct IrModule : IrBase
Module* M; Module* M;
LLGlobalVariable* fileName; LLGlobalVariable* fileName;
llvm::DICompileUnit diCompileUnit;
}; };
#endif #endif

View file

@ -32,7 +32,7 @@ struct IrStruct : IrBase
bool packed; bool packed;
/// Composite type debug description. /// Composite type debug description.
llvm::DICompositeType diCompositeType; llvm::DIType diCompositeType;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////