forked from OSchip/llvm-project
Refactor. Global variables are part of compile unit so let CompileUnit create new global variable.
llvm-svn: 137621
This commit is contained in:
parent
0a0ba9d883
commit
dfd6ec3ce1
|
@ -291,6 +291,9 @@ namespace llvm {
|
|||
return getFieldAs<DIFile>(3).getFilename();
|
||||
}
|
||||
|
||||
/// isUnsignedDIType - Return true if type encoding is unsigned.
|
||||
bool isUnsignedDIType();
|
||||
|
||||
/// replaceAllUsesWith - Replace all uses of debug info referenced by
|
||||
/// this descriptor.
|
||||
void replaceAllUsesWith(DIDescriptor &D);
|
||||
|
@ -714,6 +717,10 @@ namespace llvm {
|
|||
/// getDICompositeType - Find underlying composite type.
|
||||
DICompositeType getDICompositeType(DIType T);
|
||||
|
||||
/// isSubprogramContext - Return true if Context is either a subprogram
|
||||
/// or another context nested inside a subprogram.
|
||||
bool isSubprogramContext(const MDNode *Context);
|
||||
|
||||
/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
|
||||
/// to hold function specific information.
|
||||
NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, StringRef Name);
|
||||
|
|
|
@ -328,6 +328,22 @@ void DIType::replaceAllUsesWith(MDNode *D) {
|
|||
}
|
||||
}
|
||||
|
||||
/// isUnsignedDIType - Return true if type encoding is unsigned.
|
||||
bool DIType::isUnsignedDIType() {
|
||||
DIDerivedType DTy(DbgNode);
|
||||
if (DTy.Verify())
|
||||
return DTy.getTypeDerivedFrom().isUnsignedDIType();
|
||||
|
||||
DIBasicType BTy(DbgNode);
|
||||
if (BTy.Verify()) {
|
||||
unsigned Encoding = BTy.getEncoding();
|
||||
if (Encoding == dwarf::DW_ATE_unsigned ||
|
||||
Encoding == dwarf::DW_ATE_unsigned_char)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Verify - Verify that a compile unit is well formed.
|
||||
bool DICompileUnit::Verify() const {
|
||||
if (!DbgNode)
|
||||
|
@ -1014,3 +1030,17 @@ DICompositeType llvm::getDICompositeType(DIType T) {
|
|||
|
||||
return DICompositeType();
|
||||
}
|
||||
|
||||
/// isSubprogramContext - Return true if Context is either a subprogram
|
||||
/// or another context nested inside a subprogram.
|
||||
bool llvm::isSubprogramContext(const MDNode *Context) {
|
||||
if (!Context)
|
||||
return false;
|
||||
DIDescriptor D(Context);
|
||||
if (D.isSubprogram())
|
||||
return true;
|
||||
if (D.isType())
|
||||
return isSubprogramContext(DIType(Context).getContext());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
#include "DwarfCompileUnit.h"
|
||||
#include "DwarfDebug.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Analysis/DIBuilder.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
@ -994,6 +997,112 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
|
|||
return SPDie;
|
||||
}
|
||||
|
||||
// Return const expression if value is a GEP to access merged global
|
||||
// constant. e.g.
|
||||
// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
|
||||
static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
|
||||
const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
|
||||
if (!CE || CE->getNumOperands() != 3 ||
|
||||
CE->getOpcode() != Instruction::GetElementPtr)
|
||||
return NULL;
|
||||
|
||||
// First operand points to a global struct.
|
||||
Value *Ptr = CE->getOperand(0);
|
||||
if (!isa<GlobalValue>(Ptr) ||
|
||||
!isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
|
||||
return NULL;
|
||||
|
||||
// Second operand is zero.
|
||||
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
|
||||
if (!CI || !CI->isZero())
|
||||
return NULL;
|
||||
|
||||
// Third operand is offset.
|
||||
if (!isa<ConstantInt>(CE->getOperand(2)))
|
||||
return NULL;
|
||||
|
||||
return CE;
|
||||
}
|
||||
|
||||
/// createGlobalVariableDIE - create global variable DIE.
|
||||
void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
|
||||
DIGlobalVariable GV(N);
|
||||
|
||||
// Check for pre-existence.
|
||||
if (getDIE(GV))
|
||||
return;
|
||||
|
||||
DIType GTy = GV.getType();
|
||||
DIE *VariableDIE = new DIE(GV.getTag());
|
||||
|
||||
bool isGlobalVariable = GV.getGlobal() != NULL;
|
||||
|
||||
// Add name.
|
||||
addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string,
|
||||
GV.getDisplayName());
|
||||
StringRef LinkageName = GV.getLinkageName();
|
||||
if (!LinkageName.empty() && isGlobalVariable)
|
||||
addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
|
||||
dwarf::DW_FORM_string,
|
||||
getRealLinkageName(LinkageName));
|
||||
// Add type.
|
||||
addType(VariableDIE, GTy);
|
||||
|
||||
// Add scoping info.
|
||||
if (!GV.isLocalToUnit()) {
|
||||
addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
|
||||
// Expose as global.
|
||||
addGlobal(GV.getName(), VariableDIE);
|
||||
}
|
||||
// Add line number info.
|
||||
addSourceLine(VariableDIE, GV);
|
||||
// Add to map.
|
||||
insertDIE(N, VariableDIE);
|
||||
// Add to context owner.
|
||||
DIDescriptor GVContext = GV.getContext();
|
||||
addToContextOwner(VariableDIE, GVContext);
|
||||
// Add location.
|
||||
if (isGlobalVariable) {
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
|
||||
addLabel(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->Mang->getSymbol(GV.getGlobal()));
|
||||
// Do not create specification DIE if context is either compile unit
|
||||
// or a subprogram.
|
||||
if (GV.isDefinition() && !GVContext.isCompileUnit() &&
|
||||
!GVContext.isFile() && !isSubprogramContext(GVContext)) {
|
||||
// Create specification DIE.
|
||||
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
|
||||
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
|
||||
dwarf::DW_FORM_ref4, VariableDIE);
|
||||
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
|
||||
addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
|
||||
1);
|
||||
addDie(VariableSpecDIE);
|
||||
} else {
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
|
||||
}
|
||||
} else if (const ConstantInt *CI =
|
||||
dyn_cast_or_null<ConstantInt>(GV.getConstant()))
|
||||
addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
|
||||
else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
|
||||
// GV is a merged global.
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
Value *Ptr = CE->getOperand(0);
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
|
||||
addLabel(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
|
||||
addUInt(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
|
||||
void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
|
||||
DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
|
||||
|
|
|
@ -250,6 +250,9 @@ public:
|
|||
/// information entry.
|
||||
DIEEntry *createDIEEntry(DIE *Entry);
|
||||
|
||||
/// createGlobalVariableDIE - create global variable DIE.
|
||||
void createGlobalVariableDIE(const MDNode *N);
|
||||
|
||||
void addPubTypes(DISubprogram SP);
|
||||
|
||||
/// constructTypeDIE - Construct basic type die from DIBasicType.
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "llvm/MC/MCSection.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
|
@ -179,19 +178,6 @@ static StringRef getRealLinkageName(StringRef LinkageName) {
|
|||
return LinkageName;
|
||||
}
|
||||
|
||||
/// isSubprogramContext - Return true if Context is either a subprogram
|
||||
/// or another context nested inside a subprogram.
|
||||
static bool isSubprogramContext(const MDNode *Context) {
|
||||
if (!Context)
|
||||
return false;
|
||||
DIDescriptor D(Context);
|
||||
if (D.isSubprogram())
|
||||
return true;
|
||||
if (D.isType())
|
||||
return isSubprogramContext(DIType(Context).getContext());
|
||||
return false;
|
||||
}
|
||||
|
||||
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
|
||||
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
|
||||
/// If there are global variables in this scope then create and insert
|
||||
|
@ -385,22 +371,6 @@ DIE *DwarfDebug::constructInlinedScopeDIE(LexicalScope *Scope) {
|
|||
return ScopeDIE;
|
||||
}
|
||||
|
||||
/// isUnsignedDIType - Return true if type encoding is unsigned.
|
||||
static bool isUnsignedDIType(DIType Ty) {
|
||||
DIDerivedType DTy(Ty);
|
||||
if (DTy.Verify())
|
||||
return isUnsignedDIType(DTy.getTypeDerivedFrom());
|
||||
|
||||
DIBasicType BTy(Ty);
|
||||
if (BTy.Verify()) {
|
||||
unsigned Encoding = BTy.getEncoding();
|
||||
if (Encoding == dwarf::DW_ATE_unsigned ||
|
||||
Encoding == dwarf::DW_ATE_unsigned_char)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
|
||||
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, LexicalScope *Scope) {
|
||||
StringRef Name = DV->getName();
|
||||
|
@ -504,7 +474,7 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, LexicalScope *Scope) {
|
|||
updated =
|
||||
VariableCU->addConstantValue(VariableDie,
|
||||
DVInsn->getOperand(0).getCImm(),
|
||||
isUnsignedDIType(DV->getType()));
|
||||
DV->getType().isUnsignedDIType());
|
||||
} else {
|
||||
VariableCU->addVariableAddress(DV, VariableDie,
|
||||
Asm->getDebugValueLocation(DVInsn));
|
||||
|
@ -701,33 +671,6 @@ CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const {
|
|||
return I->second;
|
||||
}
|
||||
|
||||
// Return const expression if value is a GEP to access merged global
|
||||
// constant. e.g.
|
||||
// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
|
||||
static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
|
||||
const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
|
||||
if (!CE || CE->getNumOperands() != 3 ||
|
||||
CE->getOpcode() != Instruction::GetElementPtr)
|
||||
return NULL;
|
||||
|
||||
// First operand points to a global struct.
|
||||
Value *Ptr = CE->getOperand(0);
|
||||
if (!isa<GlobalValue>(Ptr) ||
|
||||
!isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
|
||||
return NULL;
|
||||
|
||||
// Second operand is zero.
|
||||
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
|
||||
if (!CI || !CI->isZero())
|
||||
return NULL;
|
||||
|
||||
// Third operand is offset.
|
||||
if (!isa<ConstantInt>(CE->getOperand(2)))
|
||||
return NULL;
|
||||
|
||||
return CE;
|
||||
}
|
||||
|
||||
/// constructGlobalVariableDIE - Construct global variable DIE.
|
||||
void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {
|
||||
DIGlobalVariable GV(N);
|
||||
|
@ -738,77 +681,7 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {
|
|||
|
||||
// Check for pre-existence.
|
||||
CompileUnit *TheCU = getCompileUnit(N);
|
||||
if (TheCU->getDIE(GV))
|
||||
return;
|
||||
|
||||
DIType GTy = GV.getType();
|
||||
DIE *VariableDIE = new DIE(GV.getTag());
|
||||
|
||||
bool isGlobalVariable = GV.getGlobal() != NULL;
|
||||
|
||||
// Add name.
|
||||
TheCU->addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string,
|
||||
GV.getDisplayName());
|
||||
StringRef LinkageName = GV.getLinkageName();
|
||||
if (!LinkageName.empty() && isGlobalVariable)
|
||||
TheCU->addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
|
||||
dwarf::DW_FORM_string,
|
||||
getRealLinkageName(LinkageName));
|
||||
// Add type.
|
||||
TheCU->addType(VariableDIE, GTy);
|
||||
|
||||
// Add scoping info.
|
||||
if (!GV.isLocalToUnit()) {
|
||||
TheCU->addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
|
||||
// Expose as global.
|
||||
TheCU->addGlobal(GV.getName(), VariableDIE);
|
||||
}
|
||||
// Add line number info.
|
||||
TheCU->addSourceLine(VariableDIE, GV);
|
||||
// Add to map.
|
||||
TheCU->insertDIE(N, VariableDIE);
|
||||
// Add to context owner.
|
||||
DIDescriptor GVContext = GV.getContext();
|
||||
TheCU->addToContextOwner(VariableDIE, GVContext);
|
||||
// Add location.
|
||||
if (isGlobalVariable) {
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
|
||||
TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->Mang->getSymbol(GV.getGlobal()));
|
||||
// Do not create specification DIE if context is either compile unit
|
||||
// or a subprogram.
|
||||
if (GV.isDefinition() && !GVContext.isCompileUnit() &&
|
||||
!GVContext.isFile() && !isSubprogramContext(GVContext)) {
|
||||
// Create specification DIE.
|
||||
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
|
||||
TheCU->addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
|
||||
dwarf::DW_FORM_ref4, VariableDIE);
|
||||
TheCU->addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
|
||||
TheCU->addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
|
||||
1);
|
||||
TheCU->addDie(VariableSpecDIE);
|
||||
} else {
|
||||
TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
|
||||
}
|
||||
} else if (const ConstantInt *CI =
|
||||
dyn_cast_or_null<ConstantInt>(GV.getConstant()))
|
||||
TheCU->addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy));
|
||||
else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
|
||||
// GV is a merged global.
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
Value *Ptr = CE->getOperand(0);
|
||||
TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
|
||||
TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
|
||||
TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
|
||||
TheCU->addUInt(Block, 0, dwarf::DW_FORM_udata,
|
||||
Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
|
||||
TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
|
||||
TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
|
||||
}
|
||||
|
||||
TheCU->createGlobalVariableDIE(N);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue