Skip to content

Commit

Permalink
Merge pull request #49 from schweitzpgi/release_60
Browse files Browse the repository at this point in the history
Changes to support the generation of DW_TAG_common_block (DWARF debug…
  • Loading branch information
sscalpone authored Oct 2, 2018
2 parents d8b3008 + 0f8087d commit e759b6c
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 59 deletions.
1 change: 1 addition & 0 deletions include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ enum MetadataCodes {
METADATA_STRING_TYPE = 40, // [distinct, name, size, align, ...]
METADATA_FORTRAN_ARRAY_TYPE = 41, // [distinct, name, [bounds ...], ...]
METADATA_FORTRAN_SUBRANGE = 42, // [distinct, lbound, lbnde, ubound, ubnde]
METADATA_COMMON_BLOCK = 43, // [distinct, scope, name, variable,...]
};

// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
Expand Down
11 changes: 11 additions & 0 deletions include/llvm/IR/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,17 @@ namespace llvm {
DITemplateParameterArray TParams = nullptr,
DITypeArray ThrownTypes = nullptr);

/// Create common block entry for a Fortran common block
/// \param Scope Scope of this common block
/// \param Name The name of this common block
/// \param File The file this common block is defined
/// \param LineNo Line number
/// \param VarList List of variables that a located in common block
/// \param AlignInBits Common block alignment
DICommonBlock *createCommonBlock(DIScope *Scope, DIGlobalVariable *decl,
StringRef Name, DIFile *File,
unsigned LineNo, uint32_t AlignInBits = 0);

/// This creates new descriptor for a namespace with the specified
/// parent scope.
/// \param Scope Namespace scope
Expand Down
64 changes: 64 additions & 0 deletions include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class DINode : public MDNode {
case DILexicalBlockKind:
case DILexicalBlockFileKind:
case DINamespaceKind:
case DICommonBlockKind:
case DITemplateTypeParameterKind:
case DITemplateValueParameterKind:
case DIGlobalVariableKind:
Expand Down Expand Up @@ -528,6 +529,7 @@ class DIScope : public DINode {
case DILexicalBlockKind:
case DILexicalBlockFileKind:
case DINamespaceKind:
case DICommonBlockKind:
case DIModuleKind:
return true;
}
Expand Down Expand Up @@ -2653,6 +2655,68 @@ class DIGlobalVariable : public DIVariable {
}
};

class DICommonBlock : public DIScope {
unsigned LineNo;
uint32_t AlignInBits;

friend class LLVMContextImpl;
friend class MDNode;

DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
uint32_t AlignInBits, ArrayRef<Metadata *> Ops)
: DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
Ops), LineNo(LineNo), AlignInBits(AlignInBits) {}
~DICommonBlock() = default;

static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
DIGlobalVariable *Decl, StringRef Name,
DIFile *File, unsigned LineNo,
uint32_t AlignInBits, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
File, LineNo, AlignInBits, Storage, ShouldCreate);
}
static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *Decl, MDString *Name, Metadata *File,
unsigned LineNo, uint32_t AlignInBits,
StorageType Storage, bool ShouldCreate = true);

TempDICommonBlock cloneImpl() const {
return getTemporary(getContext(), getScope(), getDecl(), getName(),
getFile(), getLineNo(), getAlignInBits());
}

public:
DEFINE_MDNODE_GET(DICommonBlock,
(DIScope *Scope, DIGlobalVariable *Decl, StringRef Name,
DIFile *File, unsigned LineNo, uint32_t AlignInBits),
(Scope, Decl, Name, File, LineNo, AlignInBits))
DEFINE_MDNODE_GET(DICommonBlock,
(Metadata *Scope, Metadata *Decl, MDString *Name,
Metadata *File, unsigned LineNo, uint32_t AlignInBits),
(Scope, Decl, Name, File, LineNo, AlignInBits))

TempDICommonBlock clone() const { return cloneImpl(); }

DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
DIGlobalVariable *getDecl() const {
return cast_or_null<DIGlobalVariable>(getRawDecl());
}
StringRef getName() const { return getStringOperand(2); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
unsigned getLineNo() const { return LineNo; }
uint32_t getAlignInBits() const { return AlignInBits; }

Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawDecl() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
Metadata *getRawFile() const { return getOperand(3); }

static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DICommonBlockKind;
}
};

/// Local variable.
///
/// TODO: Split up flags.
Expand Down
1 change: 1 addition & 0 deletions include/llvm/IR/Metadata.def
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFortranArrayType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFortranSubrange)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)

#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
Expand Down
19 changes: 19 additions & 0 deletions lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4310,6 +4310,25 @@ bool LLParser::ParseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) {
return false;
}

/// ParseDICommonBlock:
/// ::= !DICommonBlock(scope: !0, file: !2, name: "SomeNamespace", line: 9)
bool LLParser::ParseDICommonBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
OPTIONAL(declaration, MDField, ); \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

Result = GET_OR_DISTINCT(DICommonBlock,
(Context, scope.Val, declaration.Val, name.Val,
file.Val, line.Val, align.Val));
return false;
}

/// ParseDINamespace:
/// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9)
bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) {
Expand Down
12 changes: 12 additions & 0 deletions lib/Bitcode/Reader/MetadataLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
case bitc::METADATA_LEXICAL_BLOCK:
case bitc::METADATA_LEXICAL_BLOCK_FILE:
case bitc::METADATA_NAMESPACE:
case bitc::METADATA_COMMON_BLOCK:
case bitc::METADATA_MACRO:
case bitc::METADATA_MACRO_FILE:
case bitc::METADATA_TEMPLATE_TYPE:
Expand Down Expand Up @@ -1524,6 +1525,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
case bitc::METADATA_COMMON_BLOCK: {
IsDistinct = Record[0] & 1;
MetadataList.assignValue(
GET_OR_DISTINCT(DICommonBlock,
(Context, getMDOrNull(Record[1]),
getMDOrNull(Record[2]), getMDString(Record[3]),
getMDOrNull(Record[4]), Record[5], Record[6])),
NextMetadataNo);
NextMetadataNo++;
break;
}
case bitc::METADATA_NAMESPACE: {
// Newer versions of DINamespace dropped file and line.
MDString *Name;
Expand Down
17 changes: 17 additions & 0 deletions lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
void writeDILexicalBlockFile(const DILexicalBlockFile *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
void writeDICommonBlock(const DICommonBlock *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDINamespace(const DINamespace *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
void writeDIMacro(const DIMacro *N, SmallVectorImpl<uint64_t> &Record,
Expand Down Expand Up @@ -1695,6 +1697,21 @@ void ModuleBitcodeWriter::writeDILexicalBlockFile(
Record.clear();
}

void ModuleBitcodeWriter::writeDICommonBlock(const DICommonBlock *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Record.push_back(N->isDistinct());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getDecl()));
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLineNo());
Record.push_back(N->getAlignInBits());

Stream.EmitRecord(bitc::METADATA_COMMON_BLOCK, Record, Abbrev);
Record.clear();
}

void ModuleBitcodeWriter::writeDINamespace(const DINamespace *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Expand Down
147 changes: 89 additions & 58 deletions lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,59 +106,8 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID());
}

DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
// Check for pre-existence.
if (DIE *Die = getDIE(GV))
return Die;

assert(GV);

auto *GVContext = GV->getScope();
auto *GTy = DD->resolve(GV->getType());

// Construct the context before querying for the existence of the DIE in
// case such construction creates the DIE.
DIE *ContextDIE = getOrCreateContextDIE(GVContext);

// Add to map.
DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
DIScope *DeclContext;
if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
DeclContext = resolve(SDMDecl->getScope());
assert(SDMDecl->isStaticMember() && "Expected static member decl");
assert(GV->isDefinition());
// We need the declaration DIE that is in the static member's class.
DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
// If the global variable's type is different from the one in the class
// member type, assume that it's more specific and also emit it.
if (GTy != DD->resolve(SDMDecl->getBaseType()))
addType(*VariableDIE, GTy);
} else {
DeclContext = GV->getScope();
// Add name and type.
addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
addType(*VariableDIE, GTy);

// Add scoping info.
if (!GV->isLocalToUnit())
addFlag(*VariableDIE, dwarf::DW_AT_external);

// Add line number info.
addSourceLine(*VariableDIE, GV);
}

if (!GV->isDefinition())
addFlag(*VariableDIE, dwarf::DW_AT_declaration);
else
addGlobalName(GV->getName(), *VariableDIE, DeclContext);

if (uint32_t AlignInBytes = GV->getAlignInBytes())
addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
AlignInBytes);

// Add location.
void DwarfCompileUnit::addLocationAttribute(
DIE *ToDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
bool addToAccelTable = false;
DIELoc *Loc = nullptr;
std::unique_ptr<DIEDwarfExpression> DwarfExpr;
Expand All @@ -171,7 +120,7 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
// DW_AT_const_value(X).
if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
addToAccelTable = true;
addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1));
addConstantValue(*ToDIE, /*Unsigned=*/true, Expr->getElement(1));
break;
}

Expand Down Expand Up @@ -231,19 +180,101 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
}
}
if (Loc)
addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
addBlock(*ToDIE, dwarf::DW_AT_location, DwarfExpr->finalize());

if (DD->useAllLinkageNames())
addLinkageName(*VariableDIE, GV->getLinkageName());
addLinkageName(*ToDIE, GV->getLinkageName());

if (addToAccelTable) {
DD->addAccelName(GV->getName(), *VariableDIE);
DD->addAccelName(GV->getName(), *ToDIE);

// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName())
DD->addAccelName(GV->getLinkageName(), *VariableDIE);
DD->addAccelName(GV->getLinkageName(), *ToDIE);
}
}

DIE *DwarfCompileUnit::getOrCreateCommonBlock(
const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());

if (DIE *NDie = getDIE(CB))
return NDie;
DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);
StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();
addString(NDie, dwarf::DW_AT_name, Name);
addGlobalName(Name, NDie, CB->getScope());
if (CB->getFile())
addSourceLine(NDie, CB->getLineNo(), CB->getFile()->getFilename(),
CB->getFile()->getDirectory());
if (DIGlobalVariable *V = CB->getDecl())
getCU().addLocationAttribute(&NDie, V, GlobalExprs);
if (uint32_t AlignInBits = CB->getAlignInBits()) {
uint32_t AlignInBytes = AlignInBits >> 3;
addUInt(NDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, AlignInBytes);
}
return &NDie;
}

DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
// Check for pre-existence.
if (DIE *Die = getDIE(GV))
return Die;

assert(GV);

auto *GVContext = GV->getScope();
auto *GTy = DD->resolve(GV->getType());

// Construct the context before querying for the existence of the DIE in
// case such construction creates the DIE.
auto *CB = dyn_cast<DICommonBlock>(GVContext);
DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)
: getOrCreateContextDIE(GVContext);

// Add to map.
DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
DIScope *DeclContext;
if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
DeclContext = resolve(SDMDecl->getScope());
assert(SDMDecl->isStaticMember() && "Expected static member decl");
assert(GV->isDefinition());
// We need the declaration DIE that is in the static member's class.
DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
// If the global variable's type is different from the one in the class
// member type, assume that it's more specific and also emit it.
if (GTy != DD->resolve(SDMDecl->getBaseType()))
addType(*VariableDIE, GTy);
} else {
DeclContext = GV->getScope();
// Add name and type.
addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
addType(*VariableDIE, GTy);

// Add scoping info.
if (!GV->isLocalToUnit())
addFlag(*VariableDIE, dwarf::DW_AT_external);

// Add line number info.
addSourceLine(*VariableDIE, GV);
}

if (!GV->isDefinition())
addFlag(*VariableDIE, dwarf::DW_AT_declaration);
else
addGlobalName(GV->getName(), *VariableDIE, DeclContext);

if (uint32_t AlignInBytes = GV->getAlignInBytes())
addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
AlignInBytes);

// Add location.
addLocationAttribute(VariableDIE, GV, GlobalExprs);

return VariableDIE;
}
Expand Down
6 changes: 6 additions & 0 deletions lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ class DwarfCompileUnit final : public DwarfUnit {
getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
ArrayRef<GlobalExpr> GlobalExprs);

DIE *getOrCreateCommonBlock(const DICommonBlock *CB,
ArrayRef<GlobalExpr> GlobalExprs);

void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV,
ArrayRef<GlobalExpr> GlobalExprs);

/// addLabelAddress - Add a dwarf label attribute data and value using
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
void addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
Expand Down
Loading

0 comments on commit e759b6c

Please sign in to comment.