#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Analysis/ValueTracking.h"
-/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'.
-/// This is only valid when the descriptor is non-null.
-Constant *DIDescriptor::getCastToEmpty() const {
- const Type *DestTy = PointerType::getUnqual(StructType::get(NULL, NULL));
- if (isNull()) return Constant::getNullValue(DestTy);
- return ConstantExpr::getBitCast(GV, DestTy);
-}
-
//===----------------------------------------------------------------------===//
// Simple Descriptor Constructors and other Methods
//===----------------------------------------------------------------------===//
: DIGlobal(GV, dwarf::DW_TAG_variable) {}
DIBlock::DIBlock(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_lexical_block) {}
+// needed by DIVariable::getType()
+DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) {
+ if (!gv) return;
+ unsigned tag = getTag();
+ if (tag != dwarf::DW_TAG_base_type && !DIDerivedType::isDerivedType(tag) &&
+ !DICompositeType::isCompositeType(tag))
+ GV = 0;
+}
/// isDerivedType - Return true if the specified tag is legal for
/// DIDerivedType.
// DIFactory: Basic Helpers
//===----------------------------------------------------------------------===//
+DIFactory::DIFactory(Module &m) : M(m) {
+ StopPointFn = FuncStartFn = RegionStartFn = RegionEndFn = DeclareFn = 0;
+ EmptyStructPtr = PointerType::getUnqual(StructType::get(NULL, NULL));
+}
+
+/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'.
+/// This is only valid when the descriptor is non-null.
+Constant *DIFactory::getCastToEmpty(DIDescriptor D) {
+ if (D.isNull()) return Constant::getNullValue(EmptyStructPtr);
+ return ConstantExpr::getBitCast(D.getGV(), EmptyStructPtr);
+}
+
Constant *DIFactory::GetTagConstant(unsigned TAG) {
assert((TAG & DIDescriptor::VersionMask) == 0 &&
"Tag too large for debug encoding!");
- return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version6);
+ return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version7);
}
Constant *DIFactory::GetStringConstant(const std::string &String) {
/// GetOrCreateAnchor - Look up an anchor for the specified tag and name. If it
/// already exists, return it. If not, create a new one and return it.
DIAnchor DIFactory::GetOrCreateAnchor(unsigned TAG, const char *Name) {
- const Type *EltTy = StructType::get(Type::Int32Ty, Type::Int32Ty, NULL);
+ const Type *EltTy = StructType::get(Type::Int32Ty, Type::Int32Ty, NULL);
// Otherwise, create the global or return it if already in the module.
Constant *C = M.getOrInsertGlobal(Name, EltTy);
SmallVector<Constant*, 16> Elts;
for (unsigned i = 0; i != NumTys; ++i)
- Elts.push_back(Tys[i].getCastToEmpty());
+ Elts.push_back(getCastToEmpty(Tys[i]));
- const Type *EltTy = PointerType::getUnqual(StructType::get(NULL,NULL));
-
- Constant *Init = ConstantArray::get(ArrayType::get(EltTy, Elts.size()),
+ Constant *Init = ConstantArray::get(ArrayType::get(EmptyStructPtr,
+ Elts.size()),
&Elts[0], Elts.size());
// If we already have this array, just return the uniqued version.
DIDescriptor &Entry = SimpleConstantCache[Init];
const std::string &Producer) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_compile_unit),
- GetOrCreateCompileUnitAnchor().getCastToEmpty(),
+ getCastToEmpty(GetOrCreateCompileUnitAnchor()),
ConstantInt::get(Type::Int32Ty, LangID),
GetStringConstant(Filename),
GetStringConstant(Directory),
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
- unsigned Encoding) {
+ unsigned Encoding,
+ const std::string *FileName,
+ const std::string *Directory) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_base_type),
- Context.getCastToEmpty(),
+ getCastToEmpty(Context),
GetStringConstant(Name),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNumber),
ConstantInt::get(Type::Int64Ty, SizeInBits),
ConstantInt::get(Type::Int64Ty, AlignInBits),
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
- ConstantInt::get(Type::Int32Ty, Encoding)
+ ConstantInt::get(Type::Int32Ty, Encoding),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
uint64_t AlignInBits,
uint64_t OffsetInBits,
unsigned Flags,
- DIType DerivedFrom) {
+ DIType DerivedFrom,
+ const std::string *FileName,
+ const std::string *Directory) {
Constant *Elts[] = {
GetTagConstant(Tag),
- Context.getCastToEmpty(),
+ getCastToEmpty(Context),
GetStringConstant(Name),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNumber),
ConstantInt::get(Type::Int64Ty, SizeInBits),
ConstantInt::get(Type::Int64Ty, AlignInBits),
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
- DerivedFrom.getCastToEmpty()
+ getCastToEmpty(DerivedFrom),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
uint64_t OffsetInBits,
unsigned Flags,
DIType DerivedFrom,
- DIArray Elements) {
+ DIArray Elements,
+ const std::string *FileName,
+ const std::string *Directory) {
+
Constant *Elts[] = {
GetTagConstant(Tag),
- Context.getCastToEmpty(),
+ getCastToEmpty(Context),
GetStringConstant(Name),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNumber),
ConstantInt::get(Type::Int64Ty, SizeInBits),
ConstantInt::get(Type::Int64Ty, AlignInBits),
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
- DerivedFrom.getCastToEmpty(),
- Elements.getCastToEmpty()
+ getCastToEmpty(DerivedFrom),
+ getCastToEmpty(Elements),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,
bool isLocalToUnit,
- bool isDefinition) {
+ bool isDefinition,
+ const std::string *FileName,
+ const std::string *Directory) {
+
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
- GetOrCreateSubprogramAnchor().getCastToEmpty(),
- Context.getCastToEmpty(),
+ getCastToEmpty(GetOrCreateSubprogramAnchor()),
+ getCastToEmpty(Context),
GetStringConstant(Name),
GetStringConstant(DisplayName),
GetStringConstant(LinkageName),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNo),
- Type.getCastToEmpty(),
+ getCastToEmpty(Type),
ConstantInt::get(Type::Int1Ty, isLocalToUnit),
- ConstantInt::get(Type::Int1Ty, isDefinition)
+ ConstantInt::get(Type::Int1Ty, isDefinition),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
const std::string &LinkageName,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,bool isLocalToUnit,
- bool isDefinition, llvm::GlobalVariable *Val) {
-
+ bool isDefinition, llvm::GlobalVariable *Val,
+ const std::string *FileName,
+ const std::string *Directory) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_variable),
- GetOrCreateGlobalVariableAnchor().getCastToEmpty(),
- Context.getCastToEmpty(),
+ getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
+ getCastToEmpty(Context),
GetStringConstant(Name),
GetStringConstant(DisplayName),
GetStringConstant(LinkageName),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNo),
- Type.getCastToEmpty(),
+ getCastToEmpty(Type),
ConstantInt::get(Type::Int1Ty, isLocalToUnit),
ConstantInt::get(Type::Int1Ty, isDefinition),
- ConstantExpr::getBitCast(Val,
- PointerType::getUnqual(StructType::get(NULL,NULL)))
+ ConstantExpr::getBitCast(Val, EmptyStructPtr),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type) {
+ DIType Type,
+ const std::string *FileName,
+ const std::string *Directory) {
+
Constant *Elts[] = {
GetTagConstant(Tag),
- Context.getCastToEmpty(),
+ getCastToEmpty(Context),
GetStringConstant(Name),
- CompileUnit.getCastToEmpty(),
+ getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNo),
- Type.getCastToEmpty(),
+ getCastToEmpty(Type),
+ GetStringConstant(FileName ? FileName->c_str() : ""),
+ GetStringConstant(Directory ? Directory->c_str() : "")
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
DIBlock DIFactory::CreateBlock(DIDescriptor Context) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_lexical_block),
- Context.getCastToEmpty()
+ getCastToEmpty(Context)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
Value *Args[] = {
llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo),
llvm::ConstantInt::get(llvm::Type::Int32Ty, ColNo),
- CU.getCastToEmpty()
+ getCastToEmpty(CU)
};
CallInst::Create(StopPointFn, Args, Args+3, "", BB);
}
llvm::Intrinsic::dbg_func_start);
// Call llvm.dbg.func.start which also implicitly sets a stoppoint.
- CallInst::Create(FuncStartFn, SP.getCastToEmpty(), "", BB);
+ CallInst::Create(FuncStartFn, getCastToEmpty(SP), "", BB);
}
/// InsertRegionStart - Insert a new llvm.dbg.region.start intrinsic call to
RegionStartFn = llvm::Intrinsic::getDeclaration(&M,
llvm::Intrinsic::dbg_region_start);
// Call llvm.dbg.func.start.
- CallInst::Create(RegionStartFn, D.getCastToEmpty(), "", BB);
+ CallInst::Create(RegionStartFn, getCastToEmpty(D), "", BB);
}
RegionEndFn = llvm::Intrinsic::getDeclaration(&M,
llvm::Intrinsic::dbg_region_end);
- CallInst::Create(RegionEndFn, D.getCastToEmpty(), "", BB);
+ CallInst::Create(RegionEndFn, getCastToEmpty(D), "", BB);
}
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
void DIFactory::InsertDeclare(llvm::Value *Storage, DIVariable D,
BasicBlock *BB) {
// Cast the storage to a {}* for the call to llvm.dbg.declare.
- const Type *DestTy = PointerType::getUnqual(StructType::get(NULL, NULL));
- Storage = new llvm::BitCastInst(Storage, DestTy, Storage->getName(), BB);
+ Storage = new llvm::BitCastInst(Storage, EmptyStructPtr, "", BB);
if (!DeclareFn)
DeclareFn = llvm::Intrinsic::getDeclaration(&M,
llvm::Intrinsic::dbg_declare);
- Value *Args[] = { Storage, D.getCastToEmpty() };
+ Value *Args[] = { Storage, getCastToEmpty(D) };
CallInst::Create(DeclareFn, Args, Args+2, "", BB);
}
+
+namespace llvm {
+ /// Finds the stoppoint coressponding to this instruction, that is the
+ /// stoppoint that dominates this instruction
+ const DbgStopPointInst *findStopPoint(const Instruction *Inst)
+ {
+ if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst))
+ return DSI;
+
+ const BasicBlock *BB = Inst->getParent();
+ BasicBlock::const_iterator I = Inst, B;
+ do {
+ B = BB->begin();
+ // A BB consisting only of a terminator can't have a stoppoint.
+ if (I != B) {
+ do {
+ --I;
+ if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
+ return DSI;
+ } while (I != B);
+ }
+ // This BB didn't have a stoppoint: if there is only one
+ // predecessor, look for a stoppoint there.
+ // We could use getIDom(), but that would require dominator info.
+ BB = I->getParent()->getUniquePredecessor();
+ if (BB)
+ I = BB->getTerminator();
+ } while (BB != 0);
+ return 0;
+ }
+
+ /// Finds the stoppoint corresponding to first real (non-debug intrinsic)
+ /// instruction in this Basic Block, and returns the stoppoint for it.
+ const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB)
+ {
+ for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
+ if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
+ return DSI;
+ }
+ // Fallback to looking for stoppoint of unique predecessor.
+ // Useful if this BB contains no stoppoints, but unique predecessor does.
+ BB = BB->getUniquePredecessor();
+ if (BB)
+ return findStopPoint(BB->getTerminator());
+ return 0;
+ }
+
+ /// Finds the dbg.declare intrinsic corresponding to this value if any.
+ /// It looks through pointer casts too.
+ const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts)
+ {
+ if (stripCasts) {
+ V = V->stripPointerCasts();
+ // Look for the bitcast.
+ for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
+ I != E; ++I) {
+ if (isa<BitCastInst>(I))
+ return findDbgDeclare(*I, false);
+ }
+ return 0;
+ }
+
+ // Find dbg.declare among uses of the instruction.
+ for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
+ I != E; ++I) {
+ if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I))
+ return DDI;
+ }
+ return 0;
+ }
+}
+