summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp40
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp46
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h10
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp3
4 files changed, 72 insertions, 27 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 8bc5ef9..58f3aa5 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -919,6 +919,8 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
default:
llvm_unreachable("Unsupported operator!");
}
+ } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
+ GetBlockAddressSymbol(BA)->print(O, MAI);
} else {
llvm_unreachable("Unknown constant value!");
}
@@ -1366,6 +1368,7 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col,
CurDLT.Scope);
printLabel(L);
+ O << '\n';
#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
DW->SetDbgScopeBeginLabels(MI, L);
#endif
@@ -1613,6 +1616,24 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
return true;
}
+MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
+ return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock());
+}
+
+MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
+ const BasicBlock *BB) const {
+ assert(BB->hasName() &&
+ "Address of anonymous basic block not supported yet!");
+
+ // FIXME: This isn't guaranteed to produce a unique name even if the
+ // block and function have a name.
+ std::string Mangled =
+ Mang->getMangledName(F, Mang->makeNameProper(BB->getName()).c_str(),
+ /*ForcePrivate=*/true);
+
+ return OutContext.GetOrCreateSymbol(StringRef(Mangled));
+}
+
MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB"
@@ -1626,9 +1647,27 @@ MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
+ // Emit an alignment directive for this block, if needed.
if (unsigned Align = MBB->getAlignment())
EmitAlignment(Log2_32(Align));
+ // If the block has its address taken, emit a special label to satisfy
+ // references to the block. This is done so that we don't need to
+ // remember the number of this label, and so that we can make
+ // forward references to labels without knowing what their numbers
+ // will be.
+ if (MBB->hasAddressTaken()) {
+ GetBlockAddressSymbol(MBB->getBasicBlock()->getParent(),
+ MBB->getBasicBlock())->print(O, MAI);
+ O << ':';
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << " Address Taken";
+ }
+ O << '\n';
+ }
+
+ // Print the main label for the block.
if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) {
if (VerboseAsm)
O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
@@ -1639,6 +1678,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
O << '\n';
}
+ // Print some comments to accompany the label.
if (VerboseAsm) {
if (const BasicBlock *BB = MBB->getBasicBlock())
if (BB->hasName()) {
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index d50e5e3..23752c4 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -124,7 +124,7 @@ public:
//===----------------------------------------------------------------------===//
/// DbgVariable - This class is used to track local variable information.
///
-class VISIBILITY_HIDDEN DbgVariable {
+class DbgVariable {
DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index.
bool InlinedFnVar; // Variable for an inlined function.
@@ -142,7 +142,7 @@ public:
/// DbgScope - This class is used to track scope information.
///
class DbgConcreteScope;
-class VISIBILITY_HIDDEN DbgScope {
+class DbgScope {
DbgScope *Parent; // Parent to this scope.
DIDescriptor Desc; // Debug info descriptor for scope.
// FIXME use WeakVH for Desc.
@@ -1249,6 +1249,9 @@ CompileUnit &DwarfDebug::FindCompileUnit(DICompileUnit Unit) const {
DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
// Get the descriptor.
const DIVariable &VD = DV->getVariable();
+ const char *Name = VD.getName();
+ if (!Name)
+ return NULL;
// Translate tag to proper Dwarf tag. The result variable is dropped for
// now.
@@ -1267,7 +1270,6 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
// Define variable debug information entry.
DIE *VariableDie = new DIE(Tag);
- const char *Name = VD.getName();
AddString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
// Add source line info if available.
@@ -1304,15 +1306,16 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
///
DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI,
MDNode *InlinedAt) {
- DbgScope *&Slot = DbgScopeMap[N];
- if (Slot) return Slot;
+ ValueMap<MDNode *, DbgScope *>::iterator VI = DbgScopeMap.find(N);
+ if (VI != DbgScopeMap.end())
+ return VI->second;
DbgScope *Parent = NULL;
if (InlinedAt) {
DILocation IL(InlinedAt);
assert (!IL.isNull() && "Invalid InlindAt location!");
- DenseMap<MDNode *, DbgScope *>::iterator DSI =
+ ValueMap<MDNode *, DbgScope *>::iterator DSI =
DbgScopeMap.find(IL.getScope().getNode());
assert (DSI != DbgScopeMap.end() && "Unable to find InlineAt scope!");
Parent = DSI->second;
@@ -1334,17 +1337,18 @@ DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI,
assert (0 && "Unexpected scope info");
}
- Slot = new DbgScope(Parent, DIDescriptor(N), InlinedAt);
- Slot->setFirstInsn(MI);
+ DbgScope *NScope = new DbgScope(Parent, DIDescriptor(N), InlinedAt);
+ NScope->setFirstInsn(MI);
if (Parent)
- Parent->AddScope(Slot);
+ Parent->AddScope(NScope);
else
// First function is top level function.
if (!FunctionDbgScope)
- FunctionDbgScope = Slot;
+ FunctionDbgScope = NScope;
- return Slot;
+ DbgScopeMap.insert(std::make_pair(N, NScope));
+ return NScope;
}
@@ -1812,7 +1816,7 @@ void DwarfDebug::CollectVariableInfo() {
if (DV.isNull()) continue;
unsigned VSlot = VI->second;
DbgScope *Scope = NULL;
- DenseMap<MDNode *, DbgScope *>::iterator DSI =
+ ValueMap<MDNode *, DbgScope *>::iterator DSI =
DbgScopeMap.find(DV.getContext().getNode());
if (DSI != DbgScopeMap.end())
Scope = DSI->second;
@@ -1884,8 +1888,10 @@ bool DwarfDebug::ExtractScopeInformation(MachineFunction *MF) {
// If a scope's last instruction is not set then use its child scope's
// last instruction as this scope's last instrunction.
- for (DenseMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
+ for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
DE = DbgScopeMap.end(); DI != DE; ++DI) {
+ DbgScope *S = DI->second;
+ if (!S) continue;
assert (DI->second->getFirstInsn() && "Invalid first instruction!");
DI->second->FixInstructionMarkers();
assert (DI->second->getLastInsn() && "Invalid last instruction!");
@@ -1895,10 +1901,10 @@ bool DwarfDebug::ExtractScopeInformation(MachineFunction *MF) {
// and end of a scope respectively. Create an inverse map that list scopes
// starts (and ends) with an instruction. One instruction may start (or end)
// multiple scopes.
- for (DenseMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
+ for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
DE = DbgScopeMap.end(); DI != DE; ++DI) {
DbgScope *S = DI->second;
- assert (S && "DbgScope is missing!");
+ if (!S) continue;
const MachineInstr *MI = S->getFirstInsn();
assert (MI && "DbgScope does not have first instruction!");
@@ -2172,7 +2178,7 @@ void DwarfDebug::RecordVariable(MDNode *N, unsigned FrameIndex) {
if (!SP.isNull()) {
// SP is inserted into DbgAbstractScopeMap when inlined function
// start was recorded by RecordInlineFnStart.
- DenseMap<MDNode *, DbgScope *>::iterator
+ ValueMap<MDNode *, DbgScope *>::iterator
I = DbgAbstractScopeMap.find(SP.getNode());
if (I != DbgAbstractScopeMap.end()) {
InlinedVar = true;
@@ -2249,7 +2255,7 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU,
LexicalScopeStack.back()->AddConcreteInst(ConcreteScope);
// Keep track of the concrete scope that's inlined into this function.
- DenseMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator
+ ValueMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator
SI = DbgConcreteScopeMap.find(Node);
if (SI == DbgConcreteScopeMap.end())
@@ -2258,7 +2264,7 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU,
SI->second.push_back(ConcreteScope);
// Track the start label for this inlined function.
- DenseMap<MDNode *, SmallVector<unsigned, 4> >::iterator
+ ValueMap<MDNode *, SmallVector<unsigned, 4> >::iterator
I = InlineInfo.find(Node);
if (I == InlineInfo.end())
@@ -2281,7 +2287,7 @@ unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) {
DebugTimer->startTimer();
MDNode *Node = SP.getNode();
- DenseMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator
+ ValueMap<MDNode *, SmallVector<DbgScope *, 8> >::iterator
I = DbgConcreteScopeMap.find(Node);
if (I == DbgConcreteScopeMap.end()) {
@@ -2989,7 +2995,7 @@ void DwarfDebug::EmitDebugInlineInfo() {
Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version");
Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
- for (DenseMap<MDNode *, SmallVector<unsigned, 4> >::iterator
+ for (ValueMap<MDNode *, SmallVector<unsigned, 4> >::iterator
I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
MDNode *Node = I->first;
SmallVector<unsigned, 4> &Labels = I->second;
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 7f71104..ddb0a15 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ValueMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
@@ -139,7 +139,7 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
DbgScope *FunctionDbgScope;
/// DbgScopeMap - Tracks the scopes in the current function.
- DenseMap<MDNode *, DbgScope *> DbgScopeMap;
+ ValueMap<MDNode *, DbgScope *> DbgScopeMap;
/// ScopedGVs - Tracks global variables that are not at file scope.
/// For example void f() { static int b = 42; }
@@ -156,16 +156,16 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
/// DbgAbstractScopeMap - Tracks abstract instance scopes in the current
/// function.
- DenseMap<MDNode *, DbgScope *> DbgAbstractScopeMap;
+ ValueMap<MDNode *, DbgScope *> DbgAbstractScopeMap;
/// DbgConcreteScopeMap - Tracks concrete instance scopes in the current
/// function.
- DenseMap<MDNode *,
+ ValueMap<MDNode *,
SmallVector<DbgScope *, 8> > DbgConcreteScopeMap;
/// InlineInfo - Keep track of inlined functions and their location. This
/// information is used to populate debug_inlined section.
- DenseMap<MDNode *, SmallVector<unsigned, 4> > InlineInfo;
+ ValueMap<MDNode *, SmallVector<unsigned, 4> > InlineInfo;
/// AbstractInstanceRootMap - Map of abstract instance roots of inlined
/// functions. These are subroutine entries that contain a DW_AT_inline
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 06b92b7..9286ad5 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -20,14 +20,13 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
- class VISIBILITY_HIDDEN OcamlGCMetadataPrinter : public GCMetadataPrinter {
+ class OcamlGCMetadataPrinter : public GCMetadataPrinter {
public:
void beginAssembly(raw_ostream &OS, AsmPrinter &AP,
const MCAsmInfo &MAI);
OpenPOWER on IntegriCloud