Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
  • Loading branch information...
commit 1fac40d2bd2a741fd18eb90a7dd5505c2b226ff8 1 parent 5707961
@lindquist lindquist authored
View
7 dmd/expression.h
@@ -41,6 +41,7 @@ struct TemplateDeclaration;
struct ClassDeclaration;
struct HdrGenState;
struct BinExp;
+struct AssignExp;
struct InterState;
struct OverloadSet;
@@ -177,6 +178,8 @@ struct Expression : Object
virtual void cacheLvalue(IRState* irs);
llvm::Value* cachedLvalue;
+
+ virtual AssignExp* isAssignExp() { return NULL; }
#endif
};
@@ -942,7 +945,7 @@ struct DotIdExp : UnaExp
struct DotTemplateExp : UnaExp
{
TemplateDeclaration *td;
-
+
DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
@@ -1378,6 +1381,8 @@ struct AssignExp : BinExp
#if IN_LLVM
DValue* toElem(IRState* irs);
#endif
+
+ AssignExp* isAssignExp() { return this; }
};
#if IN_DMD
View
7 dmd/statement.h
@@ -141,6 +141,7 @@ struct Statement : Object
virtual ReturnStatement *isReturnStatement() { return NULL; }
virtual IfStatement *isIfStatement() { return NULL; }
virtual CaseStatement* isCaseStatement() { return NULL; }
+ virtual LabelStatement* isLabelStatement() { return NULL; }
#if IN_LLVM
virtual void toNakedIR(IRState *irs);
@@ -492,7 +493,7 @@ struct SwitchStatement : Statement
Array gotoCases; // array of unresolved GotoCaseStatement's
Array *cases; // array of CaseStatement's
int hasNoDefault; // !=0 if no default statement
-
+
// LDC
Statement *enclosingScopeExit;
@@ -536,7 +537,7 @@ struct CaseStatement : Statement
void toIR(IRState *irs);
CaseStatement* isCaseStatement() { return this; }
-
+
// LDC
llvm::BasicBlock* bodyBB;
llvm::ConstantInt* llvmIdx;
@@ -863,6 +864,8 @@ struct LabelStatement : Statement
// LDC
bool asmLabel; // for labels inside inline assembler
void toNakedIR(IRState *irs);
+
+ LabelStatement* isLabelStatement() { return this; }
};
struct LabelDsymbol : Dsymbol
View
4 gen/arrays.cpp
@@ -309,7 +309,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
LLConstant* constarr;
if (mismatch)
- constarr = LLConstantStruct::get(gIR->context(), initvals);
+ constarr = LLConstantStruct::get(gIR->context(), initvals, false); // FIXME should this pack?
else
constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals);
@@ -394,7 +394,7 @@ void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr)
{
LLConstant* values[2] = { dim, ptr };
- return LLConstantStruct::get(gIR->context(), values, 2);
+ return LLConstantStruct::get(gIR->context(), values, 2, false);
}
//////////////////////////////////////////////////////////////////////////////////////////
View
32 gen/asmstmt.cpp
@@ -94,8 +94,8 @@ void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
bool sep = 0, nsep = 0;
buf->writestring("asm { ");
-
- for (Token * t = tokens; t; t = t->next) {
+
+ for (Token * t = tokens; t; t = t->next) {
switch (t->value) {
case TOKlparen:
case TOKrparen:
@@ -161,11 +161,11 @@ Statement *AsmStatement::semantic(Scope *sc)
sc->func->inlineStatus = ILSno; // %% not sure
// %% need to set DECL_UNINLINABLE too?
sc->func->hasReturnExp = 1; // %% DMD does this, apparently...
-
+
// empty statement -- still do the above things because they might be expected?
if (! tokens)
return this;
-
+
if (!asmparser)
if (global.params.cpu == ARCHx86)
asmparser = new AsmParserx8632::AsmParser;
@@ -196,9 +196,11 @@ AsmStatement::toIR(IRState * irs)
IRAsmBlock* asmblock = irs->asmBlock;
assert(asmblock);
+ #ifndef DISABLE_DEBUG_INFO
// debug info
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
if (! asmcode)
return;
@@ -257,8 +259,7 @@ AsmStatement::toIR(IRState * irs)
break;
case Arg_FrameRelative:
// FIXME
-llvm::cout << "asm fixme Arg_FrameRelative" << std::endl;
-assert(0);
+assert(0 && "asm fixme Arg_FrameRelative");
/* if (arg->expr->op == TOKvar)
arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree;
else
@@ -275,8 +276,7 @@ assert(0);
break;*/
case Arg_LocalSize:
// FIXME
-llvm::cout << "asm fixme Arg_LocalSize" << std::endl;
-assert(0);
+assert(0 && "asm fixme Arg_LocalSize");
/* var_frame_offset = cfun->x_frame_offset;
if (var_frame_offset < 0)
var_frame_offset = - var_frame_offset;
@@ -300,7 +300,7 @@ assert(0);
// Telling GCC that callee-saved registers are clobbered makes it preserve
// those registers. This changes the stack from what a naked function
// expects.
-
+
// FIXME
// if (! irs->func->naked) {
assert(asmparser);
@@ -318,7 +318,7 @@ assert(0);
if (arg_map[i] < 0)
arg_map[i] = -arg_map[i] - 1 + n_outputs;
}
-
+
bool pct = false;
std::string::iterator
p = code->insnTemplate.begin(),
@@ -343,14 +343,14 @@ assert(0);
if (Logger::enabled()) {
Logger::cout() << "final asm: " << code->insnTemplate << '\n';
std::ostringstream ss;
-
+
ss << "GCC-style output constraints: {";
for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) {
ss << " " << *i;
}
ss << " }";
Logger::println("%s", ss.str().c_str());
-
+
ss.str("");
ss << "GCC-style input constraints: {";
for (It i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) {
@@ -358,7 +358,7 @@ assert(0);
}
ss << " }";
Logger::println("%s", ss.str().c_str());
-
+
ss.str("");
ss << "GCC-style clobbers: {";
for (It i = clobbers.begin(), e = clobbers.end(); i != e; ++i) {
@@ -379,10 +379,10 @@ assert(0);
/* LLVM doesn't support updating operands, so split into an input
* and an output operand.
*/
-
+
// Change update operand to pure output operand.
*i = mw_cns;
-
+
// Add input operand with same value, with original as "matching output".
std::ostringstream ss;
ss << '*' << (n + asmblock->outputcount);
@@ -572,7 +572,7 @@ void AsmBlockStatement::toIR(IRState* p)
for(it = asmblock->internalLabels.begin(); it != end; ++it)
if((*it)->equals(a->isBranchToLabel))
skip = true;
- if(skip)
+ if(skip)
continue;
// if we already set things up for this branch target, skip
View
24 gen/cl_helpers.cpp
@@ -17,19 +17,19 @@ static char toLower(char c) {
return c;
}
-bool FlagParser::parse(cl::Option &O, const char *ArgName, const std::string &Arg, bool &Val) {
+bool FlagParser::parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg, bool &Val) {
// Make a std::string out of it to make comparisons easier
// (and avoid repeated conversion)
- std::string argname = ArgName;
-
+ llvm::StringRef argname = ArgName;
+
typedef std::vector<std::pair<std::string, bool> >::iterator It;
for (It I = switches.begin(), E = switches.end(); I != E; ++I) {
- std::string name = I->first;
+ llvm::StringRef name = I->first;
if (name == argname
- || (name.length() < argname.length()
- && argname.substr(0, name.length()) == name
- && argname[name.length()] == '=')) {
-
+ || (name.size() < argname.size()
+ && argname.substr(0, name.size()) == name
+ && argname[name.size()] == '=')) {
+
if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) {
Val = (Val == I->second);
return false;
@@ -41,10 +41,10 @@ bool FlagParser::parse(cl::Option &O, const char *ArgName, const std::string &Ar
return true;
}
-void FlagParser::getExtraOptionNames(std::vector<const char*> &Names) {
+void FlagParser::getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names) {
typedef std::vector<std::pair<std::string, bool> >::iterator It;
for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) {
- Names.push_back(I->first.c_str());
+ Names.push_back(I->first.data());
}
}
@@ -60,7 +60,7 @@ MultiSetter::MultiSetter(bool invert, bool* p, ...) {
}
}
}
-
+
void MultiSetter::operator=(bool val) {
typedef std::vector<bool*>::iterator It;
for (It I = locations.begin(), E = locations.end(); I != E; ++I) {
@@ -72,7 +72,7 @@ void MultiSetter::operator=(bool val) {
void ArrayAdapter::push_back(const char* cstr) {
if (!cstr || !*cstr)
error("Expected argument to '-%s'", name);
-
+
if (!*arrp)
*arrp = new Array;
(*arrp)->push(mem.strdup(cstr));
View
28 gen/cl_helpers.h
@@ -10,7 +10,7 @@ struct Array;
namespace opts {
namespace cl = llvm::cl;
-
+
/// Helper class for fancier options
class FlagParser : public cl::parser<bool> {
std::vector<std::pair<std::string, bool> > switches;
@@ -21,14 +21,14 @@ namespace opts {
switches.push_back(make_pair("enable-" + Name, true));
switches.push_back(make_pair("disable-" + Name, false));
// Replace <foo> with -enable-<foo>
- O.ArgStr = switches[0].first.c_str();
+ O.ArgStr = switches[0].first.data();
}
-
- bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue, bool &Val);
-
- void getExtraOptionNames(std::vector<const char*> &Names);
+
+ bool parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef ArgValue, bool &Val);
+
+ void getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names);
};
-
+
/// Helper class for options that set multiple flags
class MultiSetter {
std::vector<bool*> locations;
@@ -36,10 +36,10 @@ namespace opts {
MultiSetter(bool); //not implemented, disable auto-conversion
public:
MultiSetter(bool invert, bool* p, ...) END_WITH_NULL;
-
+
void operator=(bool val);
};
-
+
/// Helper class to fill Array with char* when given strings
/// (Errors on empty strings)
class ArrayAdapter {
@@ -52,14 +52,14 @@ namespace opts {
assert(name);
assert(arrp);
}
-
+
void push_back(const char* cstr);
-
+
void push_back(const std::string& str) {
push_back(str.c_str());
}
};
-
+
/// Helper class to allow use of a parser<bool> with BoolOrDefault
class BoolOrDefaultAdapter {
cl::boolOrDefault value;
@@ -67,11 +67,11 @@ namespace opts {
operator cl::boolOrDefault() {
return value;
}
-
+
void operator=(cl::boolOrDefault val) {
value = val;
}
-
+
void operator=(bool val) {
*this = (val ? cl::BOU_TRUE : cl::BOU_FALSE);
}
View
10 gen/configfile.cpp
@@ -94,7 +94,7 @@ bool ConfigFile::locate(sys::Path& p, const char* argv0, void* mainAddr, const c
p.appendComponent(filename);
if (p.exists())
return true;
-
+
return false;
}
@@ -102,14 +102,14 @@ bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
{
sys::Path p;
if (!locate(p, argv0, mainAddr, filename))
- {
+ {
// failed to find cfg, users still have the DFLAGS environment var
std::cerr << "Error failed to locate the configuration file: " << filename << std::endl;
return false;
}
// save config file path for -v output
- pathstr = p.toString();
+ pathstr = p.str();
try
{
@@ -141,12 +141,12 @@ bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
for (int i=0; i<len; i++)
{
std::string v = arr[i];
-
+
// replace binpathkey with binpath
size_t p;
while (std::string::npos != (p = v.find(binpathkey)))
v.replace(p, binpathkey.size(), binpath);
-
+
switches.push_back(strdup(v.c_str()));
}
}
View
17 gen/functions.cpp
@@ -599,10 +599,11 @@ void DtoDefineFunction(FuncDeclaration* fd)
return;
}
+ #ifndef DISABLE_DEBUG_INFO
// debug info
- if (global.params.symdebug) {
+ if (global.params.symdebug)
fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd);
- }
+ #endif
Type* t = fd->type->toBasetype();
TypeFunction* f = (TypeFunction*)t;
@@ -642,8 +643,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb);
irfunction->allocapoint = allocaPoint;
+ #ifndef DISABLE_DEBUG_INFO
// debug info - after all allocas, but before any llvm.dbg.declare etc
if (global.params.symdebug) DtoDwarfFuncStart(fd);
+ #endif
// this hack makes sure the frame pointer elimination optimization is disabled.
// this this eliminates a bunch of inline asm related issues.
@@ -668,8 +671,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
fd->vthis->ir.irLocal->value = thismem;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfLocalVariable(thismem, fd->vthis);
+ #endif
#if DMDV1
if (fd->vthis->nestedref)
@@ -722,8 +727,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
irloc->value = mem;
}
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout)
DtoDwarfLocalVariable(irloc->value, vd);
+ #endif
}
}
@@ -758,7 +765,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
fd->vresult->ir.irLocal->value = DtoAlloca(fd->vresult->type, fd->vresult->toChars());
}
-
+
// copy _argptr and _arguments to a memory location
if (f->linkage == LINKd && f->varargs == 1)
{
@@ -794,9 +801,11 @@ void DtoDefineFunction(FuncDeclaration* fd)
} else if (!gIR->scopereturned()) {
// llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
// in automatically, so we do it here.
-
+
// pass the previous block into this block
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug) DtoDwarfFuncEnd(fd);
+ #endif
if (func->getReturnType() == LLType::getVoidTy(gIR->context())) {
llvm::ReturnInst::Create(gIR->context(), gIR->scopebb());
}
View
18 gen/linker.cpp
@@ -106,7 +106,7 @@ int linkExecutable(const char* argv0)
error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str());
fatal();
}
- }
+ }
// strip debug info
if (!global.params.symdebug)
@@ -222,13 +222,13 @@ int linkObjToExecutable(const char* argv0)
// find gcc for linking
llvm::sys::Path gcc = getGcc();
// get a string version for argv[0]
- std::string gccStr = gcc.toString();
+ const char* gccStr = gcc.c_str();
// build arguments
std::vector<const char*> args;
// first the program name ??
- args.push_back(gccStr.c_str());
+ args.push_back(gccStr);
// object files
for (int i = 0; i < global.params.objfiles->dim; i++)
@@ -274,7 +274,7 @@ int linkObjToExecutable(const char* argv0)
error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str());
fatal();
}
- }
+ }
// additional linker switches
for (int i = 0; i < global.params.linkswitches->dim; i++)
@@ -292,7 +292,7 @@ int linkObjToExecutable(const char* argv0)
// default libs
switch(global.params.os) {
- case OSLinux:
+ case OSLinux:
case OSMacOSX:
args.push_back("-ldl");
// fallthrough
@@ -330,12 +330,12 @@ int linkObjToExecutable(const char* argv0)
}
Logger::println("Linking with: ");
- std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
+ std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
Stream logstr = Logger::cout();
for (; I != E; ++I)
if (*I)
logstr << "'" << *I << "'" << " ";
- logstr << "\n" << std::flush;
+ logstr << "\n"; // FIXME where's flush ?
// terminate args list
@@ -349,7 +349,7 @@ int linkObjToExecutable(const char* argv0)
error("message: %s", errstr.c_str());
return status;
}
-
+
return 0;
}
@@ -375,7 +375,7 @@ int runExecutable()
// build arguments
std::vector<const char*> args;
// args[0] should be the name of the executable
- args.push_back(gExePath.toString().c_str());
+ args.push_back(gExePath.c_str());
// Skip first argument to -run; it's a D source file.
for (size_t i = 1, length = opts::runargs.size(); i < length; i++)
{
View
42 gen/llvmhelpers.cpp
@@ -160,9 +160,11 @@ void DtoAssert(Module* M, Loc loc, DValue* msg)
// call
gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
+ #ifndef DISABLE_DEBUG_INFO
// end debug info
if (global.params.symdebug)
DtoDwarfFuncEnd(gIR->func()->decl);
+ #endif
// after assert is always unreachable
gIR->ir->CreateUnreachable();
@@ -268,7 +270,7 @@ void DtoEnclosingHandlers(Loc loc, Statement* target)
{
// labels are a special case: they are not required to enclose the current scope
// for them we use the enclosing scope handler as a reference point
- LabelStatement* lblstmt = dynamic_cast<LabelStatement*>(target);
+ LabelStatement* lblstmt = target ? target->isLabelStatement() : 0;
if (lblstmt)
target = lblstmt->enclosingScopeExit;
@@ -485,7 +487,7 @@ DValue* DtoNullValue(Type* type)
}
// unknown
- llvm::cout << "unsupported: null value for " << type->toChars() << '\n';
+ error("unsupported: null value for %s", type->toChars());
assert(0);
return 0;
@@ -854,6 +856,7 @@ void DtoConstInitGlobal(VarDeclaration* vd)
gvar->setInitializer(initVal);
+ #ifndef DISABLE_DEBUG_INFO
// do debug info
if (global.params.symdebug)
{
@@ -861,6 +864,7 @@ void DtoConstInitGlobal(VarDeclaration* vd)
// keep a reference so GDCE doesn't delete it !
gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType()));
}
+ #endif
}
}
@@ -906,11 +910,11 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
ExpInitializer* ex = vd->init->isExpInitializer();
assert(ex && "ref vars must have expression initializer");
assert(ex->exp);
- AssignExp* as = dynamic_cast<AssignExp*>(ex->exp);
+ AssignExp* as = ex->exp->isAssignExp();
assert(as && "ref vars must be initialized by an assign exp");
vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal();
}
-
+
// referenced by nested delegate?
#if DMDV2
if (vd->nestedrefs.dim) {
@@ -919,7 +923,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
#endif
Logger::println("has nestedref set");
assert(vd->ir.irLocal);
-
+
DtoNestedInit(vd);
}
// normal stack variable, allocate storage on the stack if it has not already been done
@@ -937,10 +941,10 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
//allocainst->setAlignment(vd->type->alignsize()); // TODO
vd->ir.irLocal->value = allocainst;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
- {
DtoDwarfLocalVariable(allocainst, vd);
- }
+ #endif
}
else
{
@@ -1046,18 +1050,20 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
// we don't handle aliases either
assert(!var->aliassym);
-
+
// alloca if necessary
LLValue* allocaval = NULL;
if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value))
{
addr = DtoAlloca(var->type, var->toChars());
-
+
+ #ifndef DISABLE_DEBUG_INFO
// add debug info
if (global.params.symdebug)
DtoDwarfLocalVariable(addr, var);
+ #endif
}
-
+
// referenced by nested function?
#if DMDV2
if (var->nestedrefs.dim)
@@ -1294,7 +1300,7 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s
Logger::println("template instance: %s", ti->toChars());
Logger::println("template declaration: %s", td->toChars());
Logger::println("intrinsic name: %s", td->intrinsicName.c_str());
-
+
// for now use the size in bits of the first template param in the instance
assert(ti->tdtypes.dim == 1);
Type* T = (Type*)ti->tdtypes.data[0];
@@ -1307,7 +1313,7 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s
char tmp[21]; // probably excessive, but covers a uint64_t
sprintf(tmp, "%lu", (unsigned long) gTargetData->getTypeSizeInBits(DtoType(T)));
-
+
// replace # in name with bitsize
name = td->intrinsicName;
@@ -1330,7 +1336,7 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s
fatal(); // or LLVM asserts
}
}
-
+
Logger::println("final intrinsic name: %s", name.c_str());
}
@@ -1340,7 +1346,7 @@ bool mustDefineSymbol(Dsymbol* s)
{
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
- // we can't (and probably shouldn't?) define functions
+ // we can't (and probably shouldn't?) define functions
// that weren't semantic3'ed
if (fd->semanticRun < 4)
return false;
@@ -1352,7 +1358,7 @@ bool mustDefineSymbol(Dsymbol* s)
// Emit extra functions if we're inlining.
// These will get available_externally linkage,
// so they shouldn't end up in object code.
-
+
assert(fd->type->ty == Tfunction);
TypeFunction* tf = (TypeFunction*) fd->type;
// * If we define extra static constructors, static destructors
@@ -1371,7 +1377,7 @@ bool mustDefineSymbol(Dsymbol* s)
{
return true;
}
-
+
// This was only semantic'ed for inlining checks.
// We won't be inlining this, so we only need to emit a declaration.
return false;
@@ -1396,7 +1402,7 @@ bool mustDefineSymbol(Dsymbol* s)
{
if (!opts::singleObj)
return true;
-
+
if (!tinst->emittedInModule)
{
gIR->seenTemplateInstances.insert(tinst);
@@ -1404,7 +1410,7 @@ bool mustDefineSymbol(Dsymbol* s)
}
return tinst->emittedInModule == gIR->dmodule;
}
-
+
return s->getModule() == gIR->dmodule;
}
View
2  gen/llvmhelpers.h
@@ -156,7 +156,7 @@ LLValue* makeLValue(Loc& loc, DValue* value);
////////////////////////////////////////////
/// convert DMD calling conv to LLVM
-unsigned DtoCallingConv(Loc loc, LINK l);
+llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l);
///
TypeFunction* DtoTypeFunction(DValue* fnval);
View
7 gen/logger.cpp
@@ -12,7 +12,7 @@
#include "llvm/GlobalValue.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Assembly/Writer.h"
#include "gen/logger.h"
@@ -27,10 +27,11 @@ void Stream::writeValue(std::ostream& OS, const llvm::Value& V) {
// Constants don't always get their types pretty-printed.
// (Only treat non-global constants like this, so that e.g. global variables
// still get their initializers printed)
+ llvm::raw_os_ostream raw(OS);
if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V))
- llvm::WriteAsOperand(OS, &V, true, gIR->module);
+ llvm::WriteAsOperand(raw, &V, true, gIR->module);
else
- OS << V;
+ V.print(raw);
}
namespace Logger
View
22 gen/logger.h
@@ -20,36 +20,38 @@ struct Loc;
class Stream {
std::ostream* OS;
-
+
public:
Stream() : OS(0) {}
Stream(std::ostream* S) : OS(S) {}
Stream(std::ostream& S) : OS(&S) {}
-
+
+ /*
Stream operator << (std::ios_base &(*Func)(std::ios_base&)) {
if (OS) *OS << Func;
return *this;
}
-
+ */
+
Stream operator << (std::ostream &(*Func)(std::ostream&)) {
- if (OS) *OS << Func;
+ if (OS) Func(*OS);
return *this;
}
-
+
template<typename Ty>
Stream& operator << (const Ty& Thing) {
if (OS)
Writer<Ty, sizeof(sfinae_bait(Thing))>::write(*OS, Thing);
return *this;
}
-
+
private:
// Implementation details to treat llvm::Value, llvm::Type and their
// subclasses specially (to pretty-print types).
-
+
static void writeType(std::ostream& OS, const llvm::Type& Ty);
static void writeValue(std::ostream& OS, const llvm::Value& Ty);
-
+
template<typename Ty, int N> friend struct Writer;
// error: function template partial specialization is not allowed
// So I guess type partial specialization + member function will have to do...
@@ -59,7 +61,7 @@ class Stream {
OS << Thing;
}
};
-
+
template<typename Ty>
struct Writer<Ty, 1> {
static void write(std::ostream& OS, const llvm::Type& Thing) {
@@ -69,7 +71,7 @@ class Stream {
Stream::writeValue(OS, Thing);
}
};
-
+
// NOT IMPLEMENTED
char sfinae_bait(const llvm::Type&);
char sfinae_bait(const llvm::Value&);
View
41 gen/main.cpp
@@ -148,7 +148,7 @@ int main(int argc, char** argv)
global.params.libfiles = new Array();
global.params.objfiles = new Array();
global.params.ddocfiles = new Array();
-
+
global.params.moduleDeps = NULL;
global.params.moduleDepsFile = NULL;
@@ -223,12 +223,12 @@ int main(int argc, char** argv)
// String options: std::string --> char*
initFromString(global.params.objname, objectFile);
initFromString(global.params.objdir, objectDir);
-
+
initFromString(global.params.docdir, ddocDir);
initFromString(global.params.docname, ddocFile);
global.params.doDocComments |=
global.params.docdir || global.params.docname;
-
+
#ifdef _DH
initFromString(global.params.hdrdir, hdrDir);
initFromString(global.params.hdrname, hdrFile);
@@ -237,9 +237,9 @@ int main(int argc, char** argv)
#endif
initFromString(global.params.moduleDepsFile, moduleDepsFile);
- if (global.params.moduleDepsFile != NULL)
- {
- global.params.moduleDeps = new OutBuffer;
+ if (global.params.moduleDepsFile != NULL)
+ {
+ global.params.moduleDeps = new OutBuffer;
}
processVersions(debugArgs, "debug",
@@ -435,7 +435,7 @@ int main(int argc, char** argv)
std::string triple = global.params.targetTriple;
// Allocate target machine.
-
+
// first initialize llvm
#define LLVM_TARGET(A) LLVMInitialize##A##TargetInfo(); LLVMInitialize##A##Target(); LLVMInitialize##A##AsmPrinter();
// this is defined to be LLVM_TARGET(target name 1) LLVM_TARGET(target name 2) ...
@@ -484,10 +484,15 @@ LDC_TARGETS
FeaturesStr = Features.getString();
}
- std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr));
- assert(target.get() && "Could not allocate target machine!");
- gTargetMachine = target.get();
- gTargetData = gTargetMachine->getTargetData();
+ // FIXME
+ //std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr));
+ //assert(target.get() && "Could not allocate target machine!");
+ //gTargetMachine = target.get();
+
+ llvm::TargetMachine* target = theTarget->createTargetMachine(triple, FeaturesStr);
+ gTargetMachine = target;
+
+ gTargetData = target->getTargetData();
// get final data layout
std::string datalayout = gTargetData->getStringRepresentation();
@@ -903,12 +908,12 @@ LDC_TARGETS
fatal();
// write module dependencies to file if requested
- if (global.params.moduleDepsFile != NULL)
- {
+ if (global.params.moduleDepsFile != NULL)
+ {
assert (global.params.moduleDepsFile != NULL);
File deps(global.params.moduleDepsFile);
- OutBuffer* ob = global.params.moduleDeps;
+ OutBuffer* ob = global.params.moduleDeps;
deps.setbuffer((void*)ob->data, ob->offset);
deps.write();
}
@@ -944,14 +949,14 @@ LDC_TARGETS
m->gendocfile();
}
}
-
+
// internal linking for singleobj
if (singleObj && llvmModules.size() > 0)
{
Module* m = (Module*)modules.data[0];
char* name = m->toChars();
char* filename = m->objfile->name->str;
-
+
llvm::Linker linker(name, name, context);
std::string errormsg;
@@ -961,12 +966,12 @@ LDC_TARGETS
error("%s", errormsg.c_str());
delete llvmModules[i];
}
-
+
m->deleteObjFile();
writeModule(linker.getModule(), filename);
global.params.objfiles->push(filename);
}
-
+
backend_term();
if (global.errors)
fatal();
View
14 gen/optimizer.cpp
@@ -95,7 +95,7 @@ bool optimize() {
static void addPass(PassManager& pm, Pass* pass) {
pm.add(pass);
-
+
if (verifyEach) pm.add(createVerifierPass());
}
@@ -107,7 +107,7 @@ static void addPassesForOptLevel(PassManager& pm) {
{
//addPass(pm, createStripDeadPrototypesPass());
addPass(pm, createGlobalDCEPass());
- addPass(pm, createRaiseAllocationsPass());
+ addPass(pm, createPromoteMemoryToRegisterPass());
addPass(pm, createCFGSimplificationPass());
if (optimizeLevel == 1)
addPass(pm, createPromoteMemoryToRegisterPass());
@@ -165,7 +165,7 @@ static void addPassesForOptLevel(PassManager& pm) {
addPass(pm, createCFGSimplificationPass());
addPass(pm, createInstructionCombiningPass());
}
-
+
// -O3
if (optimizeLevel >= 3)
{
@@ -177,7 +177,7 @@ static void addPassesForOptLevel(PassManager& pm) {
addPass(pm, createCFGSimplificationPass());
addPass(pm, createScalarReplAggregatesPass());
addPass(pm, createInstructionCombiningPass());
- addPass(pm, createCondPropagationPass());
+ addPass(pm, createConstantPropagationPass());
addPass(pm, createReassociatePass());
addPass(pm, createLoopRotatePass());
@@ -194,7 +194,7 @@ static void addPassesForOptLevel(PassManager& pm) {
addPass(pm, createSCCPPass());
addPass(pm, createInstructionCombiningPass());
- addPass(pm, createCondPropagationPass());
+ addPass(pm, createConstantPropagationPass());
addPass(pm, createDeadStoreEliminationPass());
addPass(pm, createAggressiveDCEPass());
@@ -220,9 +220,9 @@ bool ldc_optimize_module(llvm::Module* m)
return false;
PassManager pm;
-
+
if (verifyEach) pm.add(createVerifierPass());
-
+
addPass(pm, new TargetData(m));
bool optimize = optimizeLevel != 0 || doInline();
View
91 gen/passes/SimplifyDRuntimeCalls.cpp
@@ -18,6 +18,7 @@
#include "Passes.h"
+#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/IRBuilder.h"
@@ -48,25 +49,25 @@ namespace {
const TargetData *TD;
AliasAnalysis *AA;
LLVMContext *Context;
-
+
/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Value *CastToCStr(Value *V, IRBuilder<> &B);
-
+
/// EmitMemCpy - Emit a call to the memcpy function to the builder. This
/// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
- Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
+ Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
unsigned Align, IRBuilder<> &B);
public:
LibCallOptimization() { }
virtual ~LibCallOptimization() {}
-
+
/// CallOptimizer - This pure virtual method is implemented by base classes to
/// do various optimizations. If this returns null then no transformation was
/// performed. If it returns CI, then it transformed the call and CI is to be
/// deleted. If it returns something else, replace CI with the new value and
/// delete CI.
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
-
+
Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
AliasAnalysis& AA, IRBuilder<> &B) {
Caller = CI->getParent()->getParent();
@@ -116,27 +117,27 @@ struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization {
FT->getParamType(1) != FT->getParamType(2) ||
FT->getParamType(3) != FT->getReturnType())
return 0;
-
+
// Whether or not this allocates is irrelevant if the result isn't used.
// Just delete if that's the case.
if (CI->use_empty())
return CI;
-
+
Value* NewLen = CI->getOperand(2);
if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
Value* Data = CI->getOperand(4);
-
+
// For now, we just catch the simplest of cases.
//
// TODO: Implement a more general way to compare old and new
// lengths, to catch cases like "arr.length = arr.length - 1;"
// (But beware of unsigned overflow! For example, we can't
// safely transform that example if arr.length may be 0)
-
+
// Setting length to 0 never reallocates, so replace by data argument
if (NewCst->isNullValue())
return Data;
-
+
// If both lengths are constant integers, see if NewLen <= OldLen
Value* OldLen = CI->getOperand(3);
if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen))
@@ -157,27 +158,27 @@ struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization {
if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy)
return 0;
-
+
Value* OldLen = CI->getOperand(1);
Value* OldSize = CI->getOperand(2);
Value* NewSize = CI->getOperand(3);
-
+
// If the old length was zero, always return zero.
if (Constant* LenCst = dyn_cast<Constant>(OldLen))
if (LenCst->isNullValue())
return OldLen;
-
+
// Equal sizes are much faster to check for, so do so now.
if (OldSize == NewSize)
return OldLen;
-
+
// If both sizes are constant integers, see if OldSize is a multiple of NewSize
if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize))
if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) {
// Don't crash on NewSize == 0, even though it shouldn't happen.
if (NewInt->isNullValue())
return 0;
-
+
APInt Quot, Rem;
APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem);
if (Rem == 0)
@@ -195,7 +196,7 @@ struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization {
// the start of inlined member functions)
for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) {
Instruction* User = cast<Instruction>(*I++);
-
+
if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) {
if (!Cmp->isEquality())
continue;
@@ -215,7 +216,7 @@ struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization {
}
}
}
-
+
// If it's not used (anymore), pre-emptively GC it.
if (CI->use_empty())
return CI;
@@ -235,23 +236,23 @@ struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization {
FT->getParamType(2) != VoidPtrTy ||
FT->getParamType(3) != FT->getParamType(1))
return 0;
-
+
Value* Size = CI->getOperand(2);
-
+
// Check the lengths match
if (CI->getOperand(4) != Size)
return 0;
-
+
// Assume unknown size unless we have constant size (that fits in an uint)
unsigned Sz = ~0U;
if (ConstantInt* Int = dyn_cast<ConstantInt>(Size))
if (Int->getValue().isIntN(32))
Sz = Int->getValue().getZExtValue();
-
+
// Check if the pointers may alias
if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz))
return 0;
-
+
// Equal length and the pointers definitely don't alias, so it's safe to
// replace the call with memcpy
return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B);
@@ -271,24 +272,24 @@ namespace {
///
class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass {
StringMap<LibCallOptimization*> Optimizations;
-
+
// Array operations
ArraySetLengthOpt ArraySetLength;
ArrayCastLenOpt ArrayCastLen;
ArraySliceCopyOpt ArraySliceCopy;
-
+
// GC allocations
AllocationOpt Allocation;
-
+
public:
static char ID; // Pass identification
SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
-
+
void InitOptimizations();
bool runOnFunction(Function &F);
-
+
bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA);
-
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>();
AU.addRequired<AliasAnalysis>();
@@ -302,7 +303,7 @@ X("simplify-drtcalls", "Simplify calls to D runtime");
// Public interface to the pass.
FunctionPass *createSimplifyDRuntimeCalls() {
- return new SimplifyDRuntimeCalls();
+ return new SimplifyDRuntimeCalls();
}
/// Optimizations - Populate the Optimizations map with all the optimizations
@@ -313,7 +314,7 @@ void SimplifyDRuntimeCalls::InitOptimizations() {
Optimizations["_d_arraysetlengthiT"] = &ArraySetLength;
Optimizations["_d_array_cast_len"] = &ArrayCastLen;
Optimizations["_d_array_slice_copy"] = &ArraySliceCopy;
-
+
/* Delete calls to runtime functions which aren't needed if their result is
* unused. That comes down to functions that don't do anything but
* GC-allocate and initialize some memory.
@@ -339,10 +340,10 @@ void SimplifyDRuntimeCalls::InitOptimizations() {
bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
if (Optimizations.empty())
InitOptimizations();
-
+
const TargetData &TD = getAnalysis<TargetData>();
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
-
+
// Iterate to catch opportunities opened up by other optimizations,
// such as calls that are only used as arguments to unused calls:
// When the second call gets deleted the first call will become unused, but
@@ -354,7 +355,7 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
Changed = runOnce(F, TD, AA);
EverChanged |= Changed;
} while (Changed);
-
+
return EverChanged;
}
@@ -367,33 +368,33 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnal
// Ignore non-calls.
CallInst *CI = dyn_cast<CallInst>(I++);
if (!CI) continue;
-
+
// Ignore indirect calls and calls to non-external functions.
Function *Callee = CI->getCalledFunction();
if (Callee == 0 || !Callee->isDeclaration() ||
!(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
continue;
-
+
// Ignore unknown calls.
StringMap<LibCallOptimization*>::iterator OMI =
Optimizations.find(Callee->getName());
if (OMI == Optimizations.end()) continue;
-
+
DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI);
-
+
// Set the builder to the instruction after the call.
Builder.SetInsertPoint(BB, I);
-
+
// Try to optimize this call.
Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder);
if (Result == 0) continue;
-
+
DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI;
errs() << " into: " << *Result << "\n");
-
+
// Something changed!
Changed = true;
-
+
if (Result == CI) {
assert(CI->use_empty());
++NumDeleted;
@@ -401,18 +402,18 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnal
} else {
++NumSimplified;
AA.replaceWithNewValue(CI, Result);
-
+
if (!CI->use_empty())
CI->replaceAllUsesWith(Result);
-
+
if (!Result->hasName())
Result->takeName(CI);
}
-
+
// Inspect the instruction after the call (which was potentially just
// added) next.
I = CI; ++I;
-
+
CI->eraseFromParent();
}
}
View
52 gen/statements.cpp
@@ -53,9 +53,11 @@ void ReturnStatement::toIR(IRState* p)
Logger::println("ReturnStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
-
+ #endif
+
// is there a return value expression?
if (exp || (!exp && (p->topfunc() == p->mainFunc)) )
{
@@ -78,8 +80,10 @@ void ReturnStatement::toIR(IRState* p)
// emit scopes
DtoEnclosingHandlers(loc, NULL);
+ #ifndef DISABLE_DEBUG_INFO
// emit dbg end function
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
+ #endif
// emit ret
llvm::ReturnInst::Create(gIR->context(), p->scopebb());
@@ -126,7 +130,9 @@ void ReturnStatement::toIR(IRState* p)
DtoEnclosingHandlers(loc, NULL);
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
+ #endif
llvm::ReturnInst::Create(gIR->context(), v, p->scopebb());
}
}
@@ -136,7 +142,9 @@ void ReturnStatement::toIR(IRState* p)
assert(p->topfunc()->getReturnType() == LLType::getVoidTy(gIR->context()));
DtoEnclosingHandlers(loc, NULL);
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
+ #endif
llvm::ReturnInst::Create(gIR->context(), p->scopebb());
}
@@ -153,8 +161,10 @@ void ExpStatement::toIR(IRState* p)
Logger::println("ExpStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
if (exp) {
if (global.params.llvmAnnotate)
@@ -182,8 +192,10 @@ void IfStatement::toIR(IRState* p)
Logger::println("IfStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
if (match)
DtoRawVarDeclaration(match);
@@ -270,8 +282,10 @@ void WhileStatement::toIR(IRState* p)
Logger::println("WhileStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// create while blocks
llvm::BasicBlock* oldend = gIR->scopeend();
@@ -318,8 +332,10 @@ void DoStatement::toIR(IRState* p)
Logger::println("DoStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// create while blocks
llvm::BasicBlock* oldend = gIR->scopeend();
@@ -363,8 +379,10 @@ void ForStatement::toIR(IRState* p)
Logger::println("ForStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// create for blocks
llvm::BasicBlock* oldend = gIR->scopeend();
@@ -443,8 +461,10 @@ void BreakStatement::toIR(IRState* p)
if (p->scopereturned())
return;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
if (ident != 0) {
Logger::println("ident = %s", ident->toChars());
@@ -498,8 +518,10 @@ void ContinueStatement::toIR(IRState* p)
Logger::println("ContinueStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
if (ident != 0) {
Logger::println("ident = %s", ident->toChars());
@@ -564,8 +586,10 @@ void TryFinallyStatement::toIR(IRState* p)
Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// if there's no finalbody or no body, things are simple
if (!finalbody) {
@@ -642,8 +666,10 @@ void TryCatchStatement::toIR(IRState* p)
Logger::println("TryCatchStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// create basic blocks
llvm::BasicBlock* oldend = p->scopeend();
@@ -698,13 +724,17 @@ void ThrowStatement::toIR(IRState* p)
Logger::println("ThrowStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
assert(exp);
DValue* e = exp->toElem(p);
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl);
+ #endif
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception");
//Logger::cout() << "calling: " << *fn << '\n';
@@ -780,8 +810,10 @@ void SwitchStatement::toIR(IRState* p)
Logger::println("SwitchStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
llvm::BasicBlock* oldend = gIR->scopeend();
@@ -951,8 +983,10 @@ void UnrolledLoopStatement::toIR(IRState* p)
if (!statements || !statements->dim)
return;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// DMD doesn't fold stuff like continue/break, and since this isn't really a loop
// we have to keep track of each statement and jump to the next/end on continue/break
@@ -1017,8 +1051,10 @@ void ForeachStatement::toIR(IRState* p)
Logger::println("ForeachStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
//assert(arguments->dim == 1);
assert(value != 0);
@@ -1149,8 +1185,10 @@ void ForeachRangeStatement::toIR(IRState* p)
Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// evaluate lwr/upr
assert(lwr->type->isintegral());
@@ -1298,8 +1336,10 @@ void GotoStatement::toIR(IRState* p)
Logger::println("GotoStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", p->topfunc(), oldend);
@@ -1316,8 +1356,10 @@ void GotoDefaultStatement::toIR(IRState* p)
Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", p->topfunc(), oldend);
@@ -1338,8 +1380,10 @@ void GotoCaseStatement::toIR(IRState* p)
Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", p->topfunc(), oldend);
@@ -1363,8 +1407,10 @@ void WithStatement::toIR(IRState* p)
Logger::println("WithStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
assert(exp);
assert(body);
@@ -1393,8 +1439,10 @@ void SynchronizedStatement::toIR(IRState* p)
Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// enter lock
if (exp)
@@ -1430,8 +1478,10 @@ void VolatileStatement::toIR(IRState* p)
Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
LOG_SCOPE;
+ #ifndef DISABLE_DEBUG_INFO
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
+ #endif
// mark in-volatile
// FIXME
View
6 gen/tocall.cpp
@@ -35,7 +35,7 @@ TypeFunction* DtoTypeFunction(DValue* fnval)
//////////////////////////////////////////////////////////////////////////////////////////
-unsigned DtoCallingConv(Loc loc, LINK l)
+llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l)
{
if (l == LINKc || l == LINKcpp || l == LINKintrinsic)
return llvm::CallingConv::C;
@@ -207,7 +207,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args, std::vector<llvm::Attribut
pinits.push_back(DtoConstSize_t(vtype->getNumElements()));
pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype)));
const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf());
- tiinits = LLConstantStruct::get(gIR->context(), pinits);
+ tiinits = LLConstantStruct::get(gIR->context(), pinits, false);
LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty,
true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array");
@@ -279,7 +279,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
bool nestedcall = tf->fty.arg_nest;
bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1);
- unsigned callconv = DtoCallingConv(loc, tf->linkage);
+ llvm::CallingConv::ID callconv = DtoCallingConv(loc, tf->linkage);
// get callee llvm value
LLValue* callable = DtoCallableValue(fnval);
View
8 gen/todebug.cpp
@@ -19,6 +19,8 @@
using namespace llvm::dwarf;
+#ifndef DISABLE_DEBUG_INFO
+
#define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) )
#define DBG_TYPE ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) )
#define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) )
@@ -220,7 +222,7 @@ static void add_base_fields(
}
}
-//FIXME: This does not use llvm's DIFactory as it can't
+//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)
{
@@ -530,7 +532,7 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
false, // isMain,
false // isOptimized
);
-
+
// if the linkage stays internal, we can't llvm-link the generated modules together:
// llvm's DwarfWriter uses path and filename to determine the symbol name and we'd
// end up with duplicate symbols
@@ -636,3 +638,5 @@ void DtoDwarfStopPoint(unsigned ln)
gIR->scopebb()
);
}
+
+#endif
View
14 gen/todebug.h
@@ -1,6 +1,8 @@
#ifndef LDC_GEN_TODEBUG_H
#define LDC_GEN_TODEBUG_H
+#ifndef DISABLE_DEBUG_INFO
+
void RegisterDwarfSymbols(llvm::Module* mod);
/**
@@ -19,7 +21,7 @@ llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd);
/**
* Emit the Dwarf subprogram global for a internal function.
- * This is used for generated functions like moduleinfoctors,
+ * This is used for generated functions like moduleinfoctors,
* module ctors/dtors and unittests.
* @return the Dwarf subprogram global.
*/
@@ -39,12 +41,12 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
/**
* Emits all things necessary for making debug info for a global variable vd.
- * @param ll
- * @param vd
- * @return
+ * @param ll
+ * @param vd
+ * @return
*/
llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
-#endif // LDC_GEN_TODEBUG_H
-
+#endif // DISABLE_DEBUG_INFO
+#endif // LDC_GEN_TODEBUG_H
View
10 gen/tollvm.cpp
@@ -157,7 +157,7 @@ const LLType* DtoType(Type* t)
return getVoidPtrType();
/*
- Not needed atm as VarDecls for tuples are rewritten as a string of
+ Not needed atm as VarDecls for tuples are rewritten as a string of
VarDecls for the fields (u -> _u_field_0, ...)
case Ttuple:
@@ -289,12 +289,12 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
{
assert(0 && "not global/function");
}
-
+
// The following breaks for nested naked functions and other declarations, so check for that.
bool skipNestedCheck = !mustDefineSymbol(sym);
if (FuncDeclaration* fd = sym->isFuncDeclaration())
skipNestedCheck = (fd->naked != 0);
-
+
// Any symbol nested in a function can't be referenced directly from
// outside that function, so we can give such symbols internal linkage.
// This holds even if nested indirectly, such as member functions of
@@ -313,7 +313,7 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
if (parent->isFuncDeclaration())
return llvm::GlobalValue::InternalLinkage;
}
-
+
// default to external linkage
return llvm::GlobalValue::ExternalLinkage;
}
@@ -362,7 +362,7 @@ LLValue* DtoPointedType(LLValue* ptr, LLValue* val)
return val;
}
// ptr is integer pointer
- else if (ptrTy->isInteger())
+ else if (ptrTy->isIntegerTy())
{
// val is integer
assert(valTy->isInteger());
View
67 gen/toobj.cpp
@@ -14,7 +14,6 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/System/Program.h"
@@ -22,6 +21,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "mars.h"
#include "module.h"
@@ -114,11 +114,13 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
// allocate the target abi
gABI = TargetABI::getTarget();
+ #ifndef DISABLE_DEBUG_INFO
// debug info
if (global.params.symdebug) {
RegisterDwarfSymbols(ir.module);
DtoDwarfCompileUnit(this);
}
+ #endif
// handle invalid 'objectø module
if (!ClassDeclaration::object) {
@@ -129,7 +131,7 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
error("is missing 'class ClassInfo'");
fatal();
}
-
+
LLVM_D_InitRuntime();
// process module members
@@ -225,10 +227,11 @@ void writeModule(llvm::Module* m, std::string filename)
bcpath.eraseSuffix();
bcpath.appendSuffix(std::string(global.bc_ext));
Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str());
- std::ofstream bos(bcpath.c_str(), std::ios::binary);
- if (bos.fail())
+ std::string errinfo;
+ llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::raw_fd_ostream::F_Binary);
+ if (bos.has_error())
{
- error("cannot write LLVM bitcode, failed to open file '%s'", bcpath.c_str());
+ error("cannot write LLVM bitcode file '%s': %s", bcpath.c_str(), errinfo.c_str());
fatal();
}
llvm::WriteBitcodeToFile(m, bos);
@@ -240,10 +243,11 @@ void writeModule(llvm::Module* m, std::string filename)
llpath.eraseSuffix();
llpath.appendSuffix(std::string(global.ll_ext));
Logger::println("Writing LLVM asm to: %s\n", llpath.c_str());
- std::ofstream aos(llpath.c_str());
- if (aos.fail())
+ std::string errinfo;
+ llvm::raw_fd_ostream aos(llpath.c_str(), errinfo);
+ if (aos.has_error())
{
- error("cannot write LLVM asm, failed to open file '%s'", llpath.c_str());
+ error("cannot write LLVM asm file '%s': %s", llpath.c_str(), errinfo.c_str());
fatal();
}
m->print(aos, NULL);
@@ -260,7 +264,7 @@ void writeModule(llvm::Module* m, std::string filename)
Logger::println("Writing native asm to: %s\n", spath.c_str());
std::string err;
{
- llvm::raw_fd_ostream out(spath.c_str(), false, true, err);
+ llvm::raw_fd_ostream out(spath.c_str(), err);
if (err.empty())
{
write_asm_to_file(*gTargetMachine, *m, out);
@@ -292,17 +296,13 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f
using namespace llvm;
// Build up all of the passes that we want to do to the module.
- ExistingModuleProvider Provider(&m);
- FunctionPassManager Passes(&Provider);
+ FunctionPassManager Passes(&m);
if (const TargetData *TD = Target.getTargetData())
Passes.add(new TargetData(*TD));
else
Passes.add(new TargetData(&m));
- // Ask the target to add backend passes as necessary.
- MachineCodeEmitter *MCE = 0;
-
// Last argument is enum CodeGenOpt::Level OptLevel
// debug info doesn't work properly with OptLevel != None!
CodeGenOpt::Level LastArg = CodeGenOpt::Default;
@@ -312,11 +312,8 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f
LastArg = CodeGenOpt::Aggressive;
llvm::formatted_raw_ostream fout(out);
- FileModel::Model mod = Target.addPassesToEmitFile(Passes, fout, TargetMachine::AssemblyFile, LastArg);
- assert(mod == FileModel::AsmFile);
-
- bool err = Target.addPassesToEmitFileFinish(Passes, MCE, LastArg);
- assert(!err);
+ if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg))
+ assert(0 && "no support for asm output");
Passes.doInitialization();
@@ -328,9 +325,9 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f
Passes.doFinalization();
// release module from module provider so we can delete it ourselves
- std::string Err;
- llvm::Module* rmod = Provider.releaseModule(&Err);
- assert(rmod);
+ //std::string Err;
+ //llvm::Module* rmod = Provider.releaseModule(&Err);
+ //assert(rmod);
}
/* ================================================================== */
@@ -350,14 +347,14 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath)
// and linker because we don't know where to put the _start symbol.
// GCC mysteriously knows how to do it.
std::vector<std::string> args;
- args.push_back(gcc.toString());
+ args.push_back(gcc.str());
args.push_back("-fno-strict-aliasing");
args.push_back("-O3");
args.push_back("-c");
args.push_back("-xassembler");
- args.push_back(asmpath.toString());
+ args.push_back(asmpath.str());
args.push_back("-o");
- args.push_back(objpath.toString());
+ args.push_back(objpath.str());
//FIXME: only use this if needed?
args.push_back("-fpic");
@@ -431,11 +428,13 @@ llvm::Function* build_module_ctor()
IRBuilder<> builder(bb);
// debug info
+ #ifndef DISABLE_DEBUG_INFO
LLGlobalVariable* subprog;
if(global.params.symdebug) {
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
}
+ #endif
for (size_t i=0; i<n; i++) {
llvm::Function* f = gIR->ctors[i]->ir.irFunc->func;
@@ -444,8 +443,10 @@ llvm::Function* build_module_ctor()
}
// debug info end
+ #ifndef DISABLE_DEBUG_INFO
if(global.params.symdebug)
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
+ #endif
builder.CreateRetVoid();
return fn;
@@ -475,12 +476,14 @@ static llvm::Function* build_module_dtor()
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn);
IRBuilder<> builder(bb);
+ #ifndef DISABLE_DEBUG_INFO
// debug info
LLGlobalVariable* subprog;
if(global.params.symdebug) {
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
}
+ #endif
for (size_t i=0; i<n; i++) {
llvm::Function* f = gIR->dtors[i]->ir.irFunc->func;
@@ -488,9 +491,11 @@ static llvm::Function* build_module_dtor()
call->setCallingConv(DtoCallingConv(0, LINKd));
}
+ #ifndef DISABLE_DEBUG_INFO
// debug info end
if(global.params.symdebug)
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
+ #endif
builder.CreateRetVoid();
return fn;
@@ -520,12 +525,14 @@ static llvm::Function* build_module_unittest()
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn);
IRBuilder<> builder(bb);
+ #ifndef DISABLE_DEBUG_INFO
// debug info
LLGlobalVariable* subprog;
if(global.params.symdebug) {
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV();
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
}
+ #endif
for (size_t i=0; i<n; i++) {
llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func;
@@ -533,9 +540,11 @@ static llvm::Function* build_module_unittest()
call->setCallingConv(DtoCallingConv(0, LINKd));
}
+ #ifndef DISABLE_DEBUG_INFO
// debug info end
if(global.params.symdebug)
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
+ #endif
builder.CreateRetVoid();
return fn;
@@ -578,11 +587,13 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
IRBuilder<> builder(bb);
// debug info
+ #ifndef DISABLE_DEBUG_INFO
LLGlobalVariable* subprog;
if(global.params.symdebug) {
subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV();
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
}
+ #endif
// get current beginning
LLValue* curbeg = builder.CreateLoad(mref, "current");
@@ -594,9 +605,11 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
// replace beginning
builder.CreateStore(thismref, mref);
+ #ifndef DISABLE_DEBUG_INFO
// debug info end
if(global.params.symdebug)
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
+ #endif
// return
builder.CreateRetVoid();
@@ -614,11 +627,11 @@ void Module::genmoduleinfo()
// ModuleInfo[] importedModules;
// ClassInfo[] localClasses;
// uint flags;
-//
+//
// void function() ctor;
// void function() dtor;
// void function() unitTest;
-//
+//
// void* xgetMembers;
// void function() ictor;
//
View
6 ir/irclass.cpp
@@ -121,7 +121,7 @@ LLGlobalVariable * IrStruct::getInterfaceArraySymbol()
name.append("16__interfaceInfosZ");
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl);
- classInterfacesArray = new llvm::GlobalVariable(*gIR->module,
+ classInterfacesArray = new llvm::GlobalVariable(*gIR