[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.

Initial support for debug information. Very limited, but MUCH better than nothing :)
This commit is contained in:
Tomas Lindquist Olsen
2007-11-02 01:17:26 +01:00
parent 6bb534fb2a
commit d58ce84169
17 changed files with 507 additions and 66 deletions

1
demos/readme.txt Normal file
View File

@@ -0,0 +1 @@
use rebuild with -dc=llvmdc-posix to build the demos

View File

@@ -552,6 +552,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
llvmNestedIndex = -1;
llvmFieldIndex = -1;
llvmFieldIndexOffset = 0;
llvmNeedsStorage = false;
}
Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)

View File

@@ -262,6 +262,7 @@ struct VarDeclaration : Declaration
int llvmNestedIndex;
int llvmFieldIndex;
size_t llvmFieldIndexOffset;
bool llvmNeedsStorage;
};
/**************************************************************/
@@ -525,6 +526,7 @@ struct FuncDeclaration : Declaration
llvm::Value* llvmNested;
llvm::Value* llvmArguments;
llvm::Value* llvmArgPtr;
llvm::Constant* llvmDwarfSubProgram;
};
struct FuncAliasDeclaration : FuncDeclaration

View File

@@ -3445,7 +3445,10 @@ Expression *SymOffExp::semantic(Scope *sc)
type = var->type->pointerTo();
VarDeclaration *v = var->isVarDeclaration();
if (v)
v->checkNestedReference(sc, loc);
{
v->checkNestedReference(sc, loc);
v->llvmNeedsStorage = true;
}
return this;
}
@@ -3589,6 +3592,7 @@ Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
if (v && v->canassign == 0 &&
(var->isConst() || (global.params.Dversion > 1 && var->isFinal())))
error("cannot modify final variable '%s'", var->toChars());
v->llvmNeedsStorage = true;
if (var->isCtorinit())
{ // It's only modifiable if inside the right constructor

View File

@@ -78,6 +78,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
llvmNested = NULL;
llvmArguments = NULL;
llvmArgPtr = NULL;
llvmDwarfSubProgram = NULL;
}
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)

187
gen/dwarftypes.c Normal file
View File

@@ -0,0 +1,187 @@
// Generated by llvm2cpp - DO NOT MODIFY!
#include <llvm/Module.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Constants.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Function.h>
#include <llvm/CallingConv.h>
#include <llvm/BasicBlock.h>
#include <llvm/Instructions.h>
#include <llvm/InlineAsm.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Support/MathExtras.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <algorithm>
#include <iostream>
void RegisterDwarfSymbols(llvm::Module* mod) {
using namespace llvm;
// Type Definitions
std::vector<const Type*>StructTy_llvm_dbg_anchor_type_fields;
StructTy_llvm_dbg_anchor_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_anchor_type_fields.push_back(IntegerType::get(32));
StructType* StructTy_llvm_dbg_anchor_type = StructType::get(StructTy_llvm_dbg_anchor_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.anchor.type", StructTy_llvm_dbg_anchor_type);
std::vector<const Type*>StructTy_llvm_dbg_basictype_type_fields;
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(32));
std::vector<const Type*>StructTy_1_fields;
StructType* StructTy_1 = StructType::get(StructTy_1_fields, /*isPacked=*/false);
PointerType* PointerTy_0 = PointerType::get(StructTy_1);
StructTy_llvm_dbg_basictype_type_fields.push_back(PointerTy_0);
PointerType* PointerTy_2 = PointerType::get(IntegerType::get(8));
StructTy_llvm_dbg_basictype_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_basictype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_basictype_type_fields.push_back(IntegerType::get(32));
StructType* StructTy_llvm_dbg_basictype_type = StructType::get(StructTy_llvm_dbg_basictype_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.basictype.type", StructTy_llvm_dbg_basictype_type);
std::vector<const Type*>StructTy_llvm_dbg_compile_unit_type_fields;
StructTy_llvm_dbg_compile_unit_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_compile_unit_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_compile_unit_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_compile_unit_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_compile_unit_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_compile_unit_type_fields.push_back(PointerTy_2);
StructType* StructTy_llvm_dbg_compile_unit_type = StructType::get(StructTy_llvm_dbg_compile_unit_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.compile_unit.type", StructTy_llvm_dbg_compile_unit_type);
std::vector<const Type*>StructTy_llvm_dbg_compositetype_type_fields;
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_compositetype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_compositetype_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_compositetype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_compositetype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_compositetype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_compositetype_type_fields.push_back(PointerTy_0);
StructType* StructTy_llvm_dbg_compositetype_type = StructType::get(StructTy_llvm_dbg_compositetype_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.compositetype.type", StructTy_llvm_dbg_compositetype_type);
std::vector<const Type*>StructTy_llvm_dbg_derivedtype_type_fields;
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_derivedtype_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_derivedtype_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(64));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_derivedtype_type_fields.push_back(PointerTy_0);
StructType* StructTy_llvm_dbg_derivedtype_type = StructType::get(StructTy_llvm_dbg_derivedtype_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.derivedtype.type", StructTy_llvm_dbg_derivedtype_type);
std::vector<const Type*>StructTy_llvm_dbg_global_variable_type_fields;
StructTy_llvm_dbg_global_variable_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_global_variable_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_global_variable_type_fields.push_back(IntegerType::get(1));
StructTy_llvm_dbg_global_variable_type_fields.push_back(IntegerType::get(1));
StructTy_llvm_dbg_global_variable_type_fields.push_back(PointerTy_0);
StructType* StructTy_llvm_dbg_global_variable_type = StructType::get(StructTy_llvm_dbg_global_variable_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.global_variable.type", StructTy_llvm_dbg_global_variable_type);
std::vector<const Type*>StructTy_llvm_dbg_subprogram_type_fields;
StructTy_llvm_dbg_subprogram_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_subprogram_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_subprogram_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_subprogram_type_fields.push_back(IntegerType::get(1));
StructTy_llvm_dbg_subprogram_type_fields.push_back(IntegerType::get(1));
StructType* StructTy_llvm_dbg_subprogram_type = StructType::get(StructTy_llvm_dbg_subprogram_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.subprogram.type", StructTy_llvm_dbg_subprogram_type);
std::vector<const Type*>StructTy_llvm_dbg_variable_type_fields;
StructTy_llvm_dbg_variable_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_variable_type_fields.push_back(PointerTy_2);
StructTy_llvm_dbg_variable_type_fields.push_back(PointerTy_0);
StructTy_llvm_dbg_variable_type_fields.push_back(IntegerType::get(32));
StructTy_llvm_dbg_variable_type_fields.push_back(PointerTy_0);
StructType* StructTy_llvm_dbg_variable_type = StructType::get(StructTy_llvm_dbg_variable_type_fields, /*isPacked=*/false);
mod->addTypeName("llvm.dbg.variable.type", StructTy_llvm_dbg_variable_type);
std::vector<const Type*>FuncTy_3_args;
FuncTy_3_args.push_back(PointerTy_0);
ParamAttrsList *FuncTy_3_PAL = 0;
FunctionType* FuncTy_3 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_3_args,
/*isVarArg=*/false,
/*ParamAttrs=*/FuncTy_3_PAL);
std::vector<const Type*>FuncTy_4_args;
FuncTy_4_args.push_back(IntegerType::get(32));
FuncTy_4_args.push_back(IntegerType::get(32));
FuncTy_4_args.push_back(PointerTy_0);
ParamAttrsList *FuncTy_4_PAL = 0;
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false,
/*ParamAttrs=*/FuncTy_4_PAL);
std::vector<const Type*>FuncTy_5_args;
FuncTy_5_args.push_back(PointerTy_0);
FuncTy_5_args.push_back(PointerTy_0);
ParamAttrsList *FuncTy_5_PAL = 0;
FunctionType* FuncTy_5 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_5_args,
/*isVarArg=*/false,
/*ParamAttrs=*/FuncTy_5_PAL);
// Function Declarations
Function* func_llvm_dbg_func_start = new Function(
/*Type=*/FuncTy_3,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.dbg.func.start", mod); // (external, no body)
func_llvm_dbg_func_start->setCallingConv(CallingConv::C);
Function* func_llvm_dbg_stoppoint = new Function(
/*Type=*/FuncTy_4,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.dbg.stoppoint", mod); // (external, no body)
func_llvm_dbg_stoppoint->setCallingConv(CallingConv::C);
Function* func_llvm_dbg_declare = new Function(
/*Type=*/FuncTy_5,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.dbg.declare", mod); // (external, no body)
func_llvm_dbg_declare->setCallingConv(CallingConv::C);
Function* func_llvm_dbg_region_end = new Function(
/*Type=*/FuncTy_3,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.dbg.region.end", mod); // (external, no body)
func_llvm_dbg_region_end->setCallingConv(CallingConv::C);
}

View File

@@ -38,6 +38,7 @@ IRState::IRState()
emitMain = false;
mainFunc = 0;
ir.state = this;
dwarfCompileUnit = 0;
}
IRFunction& IRState::func()

View File

@@ -162,6 +162,9 @@ struct IRState
// builder helper
IRBuilderHelper ir;
// Dwarf debugging info
llvm::GlobalVariable* dwarfCompileUnit;
};
#endif // LLVMDC_GEN_IRSTATE_H

View File

@@ -22,6 +22,7 @@
#include "gen/tollvm.h"
#include "gen/runtime.h"
#include "gen/arrays.h"
#include "gen/todebug.h"
//////////////////////////////////////////////////////////////////////////////
@@ -63,6 +64,8 @@ void ReturnStatement::toIR(IRState* p)
TypeFunction* f = p->topfunctype();
assert(f->llvmRetInPtr && f->llvmRetArg);
if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
p->exps.push_back(IRExp(NULL,exp,f->llvmRetArg));
elem* e = exp->toElem(p);
p->exps.pop_back();
@@ -93,14 +96,17 @@ void ReturnStatement::toIR(IRState* p)
assert(0);
IRFunction::FinallyVec& fin = p->func().finallys;
if (fin.empty())
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func().decl);
new llvm::ReturnInst(p->scopebb());
}
else {
new llvm::BranchInst(fin.back().retbb, p->scopebb());
}
delete e;
}
else {
if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
elem* e = exp->toElem(p);
llvm::Value* v = e->getValue();
delete e;
@@ -108,6 +114,7 @@ void ReturnStatement::toIR(IRState* p)
IRFunction::FinallyVec& fin = p->func().finallys;
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func().decl);
new llvm::ReturnInst(v, p->scopebb());
}
else {
@@ -124,6 +131,7 @@ void ReturnStatement::toIR(IRState* p)
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
IRFunction::FinallyVec& fin = p->func().finallys;
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func().decl);
new llvm::ReturnInst(p->scopebb());
}
else {
@@ -145,6 +153,9 @@ void ExpStatement::toIR(IRState* p)
Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars());
LOG_SCOPE;
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
if (exp != 0) {
elem* e = exp->toElem(p);
delete e;
@@ -473,6 +484,7 @@ void TryFinallyStatement::toIR(IRState* p)
// no outer
else
{
if (global.params.symdebug) DtoDwarfFuncEnd(p->func().decl);
llvm::Value* retval = p->func().finallyretval;
if (retval) {
retval = p->ir->CreateLoad(retval,"tmp");

183
gen/todebug.c Normal file
View File

@@ -0,0 +1,183 @@
#include "gen/llvm.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "declaration.h"
#include "module.h"
#include "mars.h"
#include "gen/todebug.h"
#include "gen/irstate.h"
#include "gen/tollvm.h"
#include "gen/logger.h"
using namespace llvm::dwarf;
static const llvm::PointerType* ptrTy(const llvm::Type* t)
{
return llvm::PointerType::get(t);
}
static const llvm::PointerType* dbgArrTy()
{
std::vector<const llvm::Type*> t;
return ptrTy(llvm::StructType::get(t));
}
static llvm::Constant* dbgToArrTy(llvm::Constant* c)
{
Logger::cout() << "casting: " << *c << '\n';
return llvm::ConstantExpr::getBitCast(c, dbgArrTy());
}
#define Ty(X) llvm::Type::X
//////////////////////////////////////////////////////////////////////////////////////////////////
static llvm::GlobalVariable* dbg_compile_units = 0;
static llvm::GlobalVariable* dbg_global_variables = 0;
static llvm::GlobalVariable* dbg_subprograms = 0;
const llvm::StructType* GetDwarfAnchorType()
{
/*
%llvm.dbg.anchor.type = type {
uint, ;; Tag = 0 + LLVMDebugVersion
uint ;; Tag of descriptors grouped by the anchor
}
*/
std::vector<const llvm::Type*> elems(2, Ty(Int32Ty));
const llvm::StructType* t = llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
/*
%llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 17 } ;; DW_TAG_compile_unit
%llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 52 } ;; DW_TAG_variable
%llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 46 } ;; DW_TAG_subprogram
*/
if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(DW_TAG_compile_unit));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module);
dbg_compile_units->setSection("llvm.metadata");
}
if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(DW_TAG_variable));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module);
dbg_global_variables->setSection("llvm.metadata");
}
if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(DW_TAG_subprogram));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module);
dbg_subprograms->setSection("llvm.metadata");
}
return t;
}
llvm::Constant* GetDwarfAnchor(llvm::dwarf::dwarf_constants c)
{
GetDwarfAnchorType();
switch (c)
{
case DW_TAG_compile_unit:
return dbg_compile_units;
case DW_TAG_variable:
return dbg_global_variables;
case DW_TAG_subprogram:
return dbg_subprograms;
}
assert(0);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
const llvm::StructType* GetDwarfCompileUnitType() {
return llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.compile_unit.type"));
}
const llvm::StructType* GetDwarfSubProgramType() {
return llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.subprogram.type"));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
{
std::vector<llvm::Constant*> vals;
vals.push_back(llvm::ConstantExpr::getAdd(
DtoConstUint(DW_TAG_compile_unit),
DtoConstUint(llvm::LLVMDebugVersion)));
vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
vals.push_back(DtoConstUint(DW_LANG_D));
vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
std::string srcpath(FileName::path(m->srcfile->name->toChars()));
srcpath.append("/");
vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
gv->setSection("llvm.metadata");
return gv;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
{
std::vector<llvm::Constant*> vals;
vals.push_back(llvm::ConstantExpr::getAdd(
DtoConstUint(DW_TAG_subprogram),
DtoConstUint(llvm::LLVMDebugVersion)));
vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_subprogram)));
vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"));
vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata"));
vals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
vals.push_back(DtoConstUint(fd->loc.linnum));
vals.push_back(llvm::ConstantPointerNull::get(dbgArrTy()));
vals.push_back(DtoConstBool(fd->protection == PROTprivate));
vals.push_back(DtoConstBool(fd->getModule() == gIR->dmodule));
llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfSubProgramType(), vals);
llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.subprogram", gIR->module);
gv->setSection("llvm.metadata");
return gv;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void DtoDwarfFuncStart(FuncDeclaration* fd)
{
assert(fd->llvmDwarfSubProgram);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram));
}
void DtoDwarfFuncEnd(FuncDeclaration* fd)
{
assert(fd->llvmDwarfSubProgram);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void DtoDwarfStopPoint(unsigned ln)
{
std::vector<llvm::Value*> args;
args.push_back(DtoConstUint(ln));
args.push_back(DtoConstUint(0));
args.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
}

20
gen/todebug.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef LLVMDC_GEN_TODEBUG_H
#define LLVMDC_GEN_TODEBUG_H
void RegisterDwarfSymbols(llvm::Module* mod);
const llvm::StructType* GetDwarfAnchorType();
const llvm::StructType* GetDwarfCompileUnitType();
const llvm::StructType* GetDwarfSubProgramType();
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m);
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
void DtoDwarfFuncStart(FuncDeclaration* fd);
void DtoDwarfFuncEnd(FuncDeclaration* fd);
void DtoDwarfStopPoint(unsigned ln);
#endif // LLVMDC_GEN_TODEBUG_H

View File

@@ -168,29 +168,17 @@ elem* VarExp::toElem(IRState* p)
// this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
vd->llvmValue = &p->func().func->getArgumentList().back();
}
if (vd->isRef() || vd->isOut()) {
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) {
e->mem = vd->llvmValue;
e->type = elem::VAR;
e->vardecl = vd;
}
else {
if (DtoIsPassedByRef(vd->type)) {
e->mem = vd->llvmValue;
e->type = elem::VAR;
}
else {
if (llvm::isa<llvm::Argument>(vd->llvmValue)) {
e->val = vd->llvmValue;
e->type = elem::VAL;
e->vardecl = vd;
}
else if (llvm::isa<llvm::AllocaInst>(vd->llvmValue)) {
e->mem = vd->llvmValue;
e->type = elem::VAR;
}
else
assert(0);
}
else if (llvm::isa<llvm::Argument>(vd->llvmValue)) {
e->val = vd->llvmValue;
e->type = elem::VAL;
e->vardecl = vd;
}
else assert(0);
}
else {
// take care of forward references of global variables
@@ -463,18 +451,6 @@ elem* AssignExp::toElem(IRState* p)
return 0;
}
// handle function argument - allocate temp storage for it :/ annoying
if (l->mem == 0) {
assert(l->val);
if (llvm::isa<llvm::Argument>(l->val))
DtoGiveArgumentStorage(l);
else {
Logger::cout() << "here it comes... " << *l->val << '\n';
assert(0);
}
}
//e->val = l->store(r->getValue());
Type* e1type = DtoDType(e1->type);
Type* e2type = DtoDType(e2->type);
TY e1ty = e1type->ty;
@@ -689,8 +665,7 @@ elem* AddAssignExp::toElem(IRState* p)
tmp = DtoPointedType(storeVal, tmp);
}*/
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(val,l->mem,p->scopebb());
e->type = elem::VAR;
@@ -762,8 +737,7 @@ elem* MinAssignExp::toElem(IRState* p)
tmp = DtoPointedType(storeVal, tmp);
}*/
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(tmp, l->mem, p->scopebb());
delete l;
@@ -814,8 +788,7 @@ elem* MulAssignExp::toElem(IRState* p)
tmp = DtoPointedType(storeVal, tmp);
}*/
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(tmp,l->mem,p->scopebb());
delete l;
@@ -881,8 +854,7 @@ elem* DivAssignExp::toElem(IRState* p)
tmp = DtoPointedType(storeVal, tmp);
}*/
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(tmp,l->mem,p->scopebb());
delete l;
@@ -948,8 +920,7 @@ elem* ModAssignExp::toElem(IRState* p)
tmp = DtoPointedType(storeVal, tmp);
}*/
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(tmp,l->mem,p->scopebb());
delete l;
@@ -1020,7 +991,7 @@ elem* CallExp::toElem(IRState* p)
va_magic = true;
}
else if (fn->funcdecl->llvmInternal == LLVMva_arg) {
Argument* fnarg = Argument::getNth(tf->parameters, 0);
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
Expression* exp = (Expression*)arguments->data[0];
elem* expelem = exp->toElem(p);
assert(expelem->mem);
@@ -2158,8 +2129,7 @@ elem* PostExp::toElem(IRState* p)
else
assert(post);
if (l->mem == 0)
DtoGiveArgumentStorage(l);
assert(l->mem);
new llvm::StoreInst(post,l->mem,p->scopebb());
delete l;
@@ -2503,8 +2473,7 @@ elem* X##AssignExp::toElem(IRState* p) \
llvm::Value* vval = v->getValue(); \
assert(vval); \
llvm::Value* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
if (u->mem == 0) \
DtoGiveArgumentStorage(u); \
assert(u->mem); \
Logger::cout() << *tmp << '|' << *u->mem << '\n'; \
new llvm::StoreInst(DtoPointedType(u->mem, tmp), u->mem, p->scopebb()); \
delete u; \

View File

@@ -482,6 +482,7 @@ llvm::Value* DtoStructZeroInit(llvm::Value* v)
llvm::Value* DtoStructCopy(llvm::Value* dst, llvm::Value* src)
{
Logger::cout() << "dst = " << *dst << " src = " << *src << '\n';
assert(dst->getType() == src->getType());
assert(gIR);
@@ -1093,20 +1094,6 @@ llvm::Function* DtoDeclareFunction(FuncDeclaration* fdecl)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoGiveArgumentStorage(elem* l)
{
assert(l->mem == 0);
assert(l->val);
assert(llvm::isa<llvm::Argument>(l->val));
assert(l->vardecl != 0);
llvm::AllocaInst* allocainst = new llvm::AllocaInst(l->val->getType(), l->val->getName()+"_storage", gIR->topallocapoint());
l->mem = allocainst;
l->vardecl->llvmValue = l->mem;
}
//////////////////////////////////////////////////////////////////////////////////////////
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty)
{
/*size_t sz = gTargetData->getTypeSize(ty);
@@ -1235,7 +1222,6 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
if (paramtype && retval->getType() != paramtype)
{
assert(retval->getType() == paramtype->getContainedType(0));
DtoGiveArgumentStorage(arg);
new llvm::StoreInst(retval, arg->mem, gIR->scopebb());
retval = arg->mem;
}
@@ -1373,6 +1359,16 @@ llvm::Constant* DtoConstString(const char* str)
llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2)
);
}
llvm::Constant* DtoConstStringPtr(const char* str, const char* section)
{
std::string s(str);
llvm::Constant* init = llvm::ConstantArray::get(s, true);
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module);
if (section) gvar->setSection(section);
llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -46,8 +46,6 @@ llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const st
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb=NULL);
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL);
void DtoGiveArgumentStorage(elem* e);
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
@@ -63,6 +61,7 @@ llvm::ConstantInt* DtoConstSize_t(size_t);
llvm::ConstantInt* DtoConstUint(unsigned i);
llvm::ConstantInt* DtoConstInt(int i);
llvm::Constant* DtoConstString(const char*);
llvm::Constant* DtoConstStringPtr(const char* str, const char* section = 0);
llvm::Constant* DtoConstBool(bool);
void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes);

View File

@@ -36,6 +36,7 @@
#include "gen/logger.h"
#include "gen/tollvm.h"
#include "gen/arrays.h"
#include "gen/todebug.h"
//////////////////////////////////////////////////////////////////////////////////////////
@@ -75,6 +76,12 @@ Module::genobjfile()
llvm::TargetMachine &targetMachine = *targetPtr.get();
gTargetData = targetMachine.getTargetData();
// debug info
if (global.params.symdebug) {
RegisterDwarfSymbols(ir.module);
ir.dwarfCompileUnit = DtoDwarfCompileUnit(this);
}
// process module members
for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
@@ -750,6 +757,11 @@ void FuncDeclaration::toObjFile()
return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete
}
// debug info
if (global.params.symdebug) {
llvmDwarfSubProgram = DtoDwarfSubProgram(this);
}
assert(f->llvmType);
const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0));
@@ -809,6 +821,29 @@ void FuncDeclaration::toObjFile()
f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb());
gIR->func().allocapoint = f->llvmAllocaPoint;
// give arguments storage
size_t n = Argument::dim(f->parameters);
for (int i=0; i < n; ++i) {
Argument* arg = Argument::getNth(f->parameters, i);
if (arg && arg->vardecl) {
VarDeclaration* vd = arg->vardecl;
if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
continue;
llvm::Value* a = vd->llvmValue;
assert(a);
std::string s(a->getName());
Logger::println("giving argument '%s' storage", s.c_str());
s.append("_storage");
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint);
gIR->ir->CreateStore(a,v);
vd->llvmValue = v;
}
else assert(0);
}
// debug info
if (global.params.symdebug) DtoDwarfFuncStart(this);
llvm::Value* parentNested = NULL;
if (FuncDeclaration* fd = toParent()->isFuncDeclaration()) {
parentNested = fd->llvmNested;
@@ -866,7 +901,7 @@ void FuncDeclaration::toObjFile()
if (!isMain()) {
if (!gIR->scopereturned()) {
// pass the previous block into this block
//new llvm::BranchInst(irs.end, irs.begin);
if (global.params.symdebug) DtoDwarfFuncEnd(this);
if (func->getReturnType() == llvm::Type::VoidTy) {
new llvm::ReturnInst(gIR->scopebb());
}

15
test/bug47.d Normal file
View File

@@ -0,0 +1,15 @@
module bug47;
bool func(bool a, bool b)
{
if (a) b = false;
return b;
}
void main()
{
assert(func(0,0) == 0);
assert(func(0,1) == 1);
assert(func(1,0) == 0);
assert(func(1,1) == 0);
}

12
test/fail1.d Normal file
View File

@@ -0,0 +1,12 @@
module fail1;
void func()
{
float* fp;
float f = *fp;
}
void main()
{
func();
}