mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Applied some recommend changes from sabre. The dominate one beginning "let the
pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. llvm-svn: 25100
This commit is contained in:
parent
9b99d8fde6
commit
61138e28ff
@ -36,7 +36,7 @@ namespace llvm {
|
||||
///
|
||||
unsigned FunctionNumber;
|
||||
|
||||
protected:
|
||||
public:
|
||||
/// Output stream on which we're printing assembly code.
|
||||
///
|
||||
std::ostream &O;
|
||||
@ -162,7 +162,8 @@ namespace llvm {
|
||||
/// HasDotTypeDotSizeDirective - True if the target has .type and .size
|
||||
/// directives, this is true for most ELF targets.
|
||||
bool HasDotTypeDotSizeDirective; // Defaults to true.
|
||||
|
||||
|
||||
protected:
|
||||
AsmPrinter(std::ostream &o, TargetMachine &TM);
|
||||
|
||||
public:
|
||||
@ -194,7 +195,7 @@ namespace llvm {
|
||||
/// doFinalization - Shut down the asmprinter. If you override this in your
|
||||
/// pass, you must make sure to call it explicitly.
|
||||
bool doFinalization(Module &M);
|
||||
|
||||
|
||||
/// SetupMachineFunction - This should be called when a new MachineFunction
|
||||
/// is being processed from runOnMachineFunction.
|
||||
void SetupMachineFunction(MachineFunction &MF);
|
||||
@ -231,43 +232,7 @@ namespace llvm {
|
||||
|
||||
private:
|
||||
void EmitXXStructorList(Constant *List);
|
||||
|
||||
public:
|
||||
/// getCommentString - get the comment string.
|
||||
///
|
||||
const char *getCommentString() {
|
||||
return CommentString;
|
||||
}
|
||||
|
||||
/// getData8bitsDirective - get the 8-bit data directive string.
|
||||
///
|
||||
const char *getData8bitsDirective() {
|
||||
return Data8bitsDirective;
|
||||
}
|
||||
|
||||
/// getData16bitsDirective - get the 16-bit data directive string.
|
||||
///
|
||||
const char *getData16bitsDirective() {
|
||||
return Data16bitsDirective;
|
||||
}
|
||||
|
||||
/// getData32bitsDirective - get the 32-bit data directive string.
|
||||
///
|
||||
const char *getData32bitsDirective() {
|
||||
return Data32bitsDirective;
|
||||
}
|
||||
|
||||
/// getData64bitsDirective - get the 64-bit data directive string.
|
||||
///
|
||||
const char *getData64bitsDirective() {
|
||||
return Data64bitsDirective;
|
||||
}
|
||||
|
||||
/// getPrivateGlobalPrefix - get private label prefix.
|
||||
///
|
||||
const char *getPrivateGlobalPrefix() {
|
||||
return PrivateGlobalPrefix;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
#ifndef LLVM_CODEGEN_DWARFPRINTER_H
|
||||
#define LLVM_CODEGEN_DWARFPRINTER_H
|
||||
|
||||
#include <iostream>
|
||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||
#include <iosfwd>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -429,6 +428,7 @@ namespace llvm {
|
||||
// Forward declarations.
|
||||
//
|
||||
class AsmPrinter;
|
||||
class MachineDebugInfo;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// DwarfWriter - emits dwarf debug and exception handling directives.
|
||||
@ -447,12 +447,28 @@ namespace llvm {
|
||||
|
||||
/// DebugInfo - Collected debug information.
|
||||
///
|
||||
MachineDebugInfo &DebugInfo;
|
||||
MachineDebugInfo *DebugInfo;
|
||||
|
||||
/// didInitial - Flag to indicate if initial emission has been done.
|
||||
///
|
||||
bool didInitial;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Properties to be set by the derived class ctor, used to configure the
|
||||
// dwarf writer.
|
||||
|
||||
/// hasLEB128 - True if target asm supports leb128 directives.
|
||||
///
|
||||
bool hasLEB128; /// Defaults to false.
|
||||
|
||||
/// hasDotLoc - True if target asm supports .loc directives.
|
||||
///
|
||||
bool hasDotLoc; /// Defaults to false.
|
||||
|
||||
/// hasDotFile - True if target asm supports .file directives.
|
||||
///
|
||||
bool hasDotFile; /// Defaults to false.
|
||||
|
||||
/// needsSet - True if target asm can't compute addresses on data
|
||||
/// directives.
|
||||
bool needsSet; /// Defaults to false.
|
||||
@ -469,94 +485,89 @@ namespace llvm {
|
||||
///
|
||||
const char *DwarfLineSection; /// Defaults to ".debug_line".
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
|
||||
public:
|
||||
|
||||
// Ctor.
|
||||
DwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
|
||||
DwarfWriter(std::ostream &o, AsmPrinter *ap)
|
||||
: O(o)
|
||||
, Asm(ap)
|
||||
, DebugInfo(di)
|
||||
, DebugInfo(NULL)
|
||||
, didInitial(false)
|
||||
, hasLEB128(false)
|
||||
, hasDotLoc(false)
|
||||
, hasDotFile(false)
|
||||
, needsSet(false)
|
||||
, DwarfAbbrevSection(".debug_abbrev")
|
||||
, DwarfInfoSection(".debug_info")
|
||||
, DwarfLineSection(".debug_line")
|
||||
{}
|
||||
|
||||
/// SetDebugInfo - Set DebugInfo at when it's know that pass manager
|
||||
/// has created it.
|
||||
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
|
||||
|
||||
/// EmitHex - Emit a hexidecimal string to the output stream.
|
||||
///
|
||||
void EmitHex(unsigned Value) {
|
||||
O << "0x"
|
||||
<< std::hex
|
||||
<< Value
|
||||
<< std::dec;
|
||||
}
|
||||
void EmitHex(unsigned Value) const;
|
||||
|
||||
/// EmitComment - Emit a simple string comment.
|
||||
///
|
||||
void EmitComment(const char *Comment) {
|
||||
O << "\t"
|
||||
<< Asm->getCommentString()
|
||||
<< " "
|
||||
<< Comment
|
||||
<< "\n";
|
||||
}
|
||||
void EmitComment(const char *Comment) const;
|
||||
|
||||
/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
|
||||
/// representing an unsigned leb128 value.
|
||||
///
|
||||
void EmitULEB128(unsigned Value) {
|
||||
do {
|
||||
unsigned Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
if (Value) Byte |= 0x80;
|
||||
EmitHex(Byte);
|
||||
if (Value) O << ", ";
|
||||
} while (Value);
|
||||
}
|
||||
void EmitULEB128(unsigned Value) const;
|
||||
|
||||
/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
|
||||
/// representing a signed leb128 value.
|
||||
///
|
||||
void EmitSLEB128(int Value) {
|
||||
int Sign = Value >> (8 * sizeof(Value) - 1);
|
||||
bool IsMore;
|
||||
|
||||
do {
|
||||
unsigned Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
|
||||
if (IsMore) Byte |= 0x80;
|
||||
EmitHex(Byte);
|
||||
if (IsMore) O << ", ";
|
||||
} while (IsMore);
|
||||
}
|
||||
void EmitSLEB128(int Value) const;
|
||||
|
||||
/// EmitLabelName - Emit label name for internal use by dwarf.
|
||||
///
|
||||
void EmitLabelName(const char *Tag, int Num) {
|
||||
O << Asm->getPrivateGlobalPrefix()
|
||||
<< "debug_"
|
||||
<< Tag
|
||||
<< Num;
|
||||
}
|
||||
void EmitLabelName(const char *Tag, int Num) const;
|
||||
|
||||
/// EmitLabel - Emit location label for internal use by dwarf.
|
||||
///
|
||||
void EmitLabel(const char *Tag, int Num) {
|
||||
EmitLabelName(Tag, Num);
|
||||
O << ":\n";
|
||||
}
|
||||
void EmitLabel(const char *Tag, int Num) const;
|
||||
|
||||
// Defined elsewhere
|
||||
|
||||
void EmitULEB128Bytes(unsigned Value, std::string Comment);
|
||||
void EmitSLEB128Bytes(int Value, std::string Comment);
|
||||
/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
|
||||
/// unsigned leb128 value. Comment is added to the end of the directive if
|
||||
/// DwarfVerbose is true (should not contain any newlines.)
|
||||
///
|
||||
void EmitULEB128Bytes(unsigned Value, const char *Comment) const;
|
||||
|
||||
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
|
||||
/// signed leb128 value. Comment is added to the end of the directive if
|
||||
/// DwarfVerbose is true (should not contain any newlines.)
|
||||
///
|
||||
void EmitSLEB128Bytes(int Value, const char *Comment) const;
|
||||
|
||||
/// EmitInitial - Emit initial dwarf declarations.
|
||||
///
|
||||
void EmitInitial() const;
|
||||
|
||||
/// ShouldEmitDwarf - Determine if dwarf declarations should be made.
|
||||
///
|
||||
bool ShouldEmitDwarf();
|
||||
|
||||
/// BeginModule - Emit all dwarf sections that should come prior to the
|
||||
/// content.
|
||||
void BeginModule();
|
||||
|
||||
/// EndModule - Emit all dwarf sections that should come after the content.
|
||||
///
|
||||
void EndModule();
|
||||
|
||||
/// BeginFunction - Emit pre-function debug information.
|
||||
///
|
||||
void BeginFunction();
|
||||
|
||||
/// EndFunction - Emit post-function debug information.
|
||||
///
|
||||
void EndFunction();
|
||||
};
|
||||
|
||||
|
@ -28,11 +28,7 @@ namespace llvm {
|
||||
///
|
||||
class MachineDebugInfo : public ImmutablePass {
|
||||
private:
|
||||
// convenience types
|
||||
typedef std::map<std::string, unsigned> StrIntMap;
|
||||
typedef StrIntMap::iterator StrIntMapIter;
|
||||
|
||||
StrIntMap SourceMap; // Map of source file path to id
|
||||
std::map<std::string, unsigned> SourceMap; // Map of source file path to id
|
||||
unsigned SourceCount; // Number of source files (used to
|
||||
// generate id)
|
||||
unsigned UniqueID; // Number used to unique labels used
|
||||
@ -50,25 +46,25 @@ public:
|
||||
/// hasInfo - Returns true if debug info is present.
|
||||
///
|
||||
// FIXME - need scheme to suppress debug output.
|
||||
bool hasInfo() { return true; }
|
||||
bool hasInfo() const { return SourceCount != 0; }
|
||||
|
||||
/// NextUniqueID - Returns a unique number for labels used by debugger.
|
||||
/// getNextUniqueID - Returns a unique number for labels used by debugger.
|
||||
///
|
||||
unsigned NextUniqueID() { return UniqueID++; }
|
||||
unsigned getNextUniqueID() { return UniqueID++; }
|
||||
|
||||
bool doInitialization();
|
||||
bool doFinalization();
|
||||
unsigned RecordSource(std::string fname, std::string dirname);
|
||||
std::vector<std::string> getSourceFiles();
|
||||
|
||||
/// getUniqueSourceID - Register a source file with debug info. Returns an id.
|
||||
///
|
||||
unsigned getUniqueSourceID(const std::string &fname,
|
||||
const std::string &dirname);
|
||||
|
||||
/// getSourceFiles - Return a vector of files. Vector index + 1 equals id.
|
||||
///
|
||||
std::vector<std::string> getSourceFiles() const;
|
||||
|
||||
}; // End class MachineDebugInfo
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME - temporary hack until we can find a place to hang debug info from.
|
||||
MachineDebugInfo &getMachineDebugInfo();
|
||||
|
||||
// FIXME - temporary hack until we can find a place to hand debug info from.
|
||||
ModulePass *createDebugInfoPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
namespace llvm {
|
||||
class TargetLowering;
|
||||
class TargetMachine;
|
||||
class MachineDebugInfo;
|
||||
class MachineFunction;
|
||||
|
||||
/// SelectionDAG class - This is used to represent a portion of an LLVM function
|
||||
@ -41,6 +42,7 @@ namespace llvm {
|
||||
class SelectionDAG {
|
||||
TargetLowering &TLI;
|
||||
MachineFunction &MF;
|
||||
MachineDebugInfo *DI;
|
||||
|
||||
// Root - The root of the entire DAG. EntryNode - The starting token.
|
||||
SDOperand Root, EntryNode;
|
||||
@ -52,7 +54,8 @@ class SelectionDAG {
|
||||
std::map<std::pair<const Value*, int>, SDNode*> ValueNodes;
|
||||
|
||||
public:
|
||||
SelectionDAG(TargetLowering &tli, MachineFunction &mf) : TLI(tli), MF(mf) {
|
||||
SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineDebugInfo *di)
|
||||
: TLI(tli), MF(mf), DI(di) {
|
||||
EntryNode = Root = getNode(ISD::EntryToken, MVT::Other);
|
||||
}
|
||||
~SelectionDAG();
|
||||
@ -60,6 +63,7 @@ public:
|
||||
MachineFunction &getMachineFunction() const { return MF; }
|
||||
const TargetMachine &getTarget() const;
|
||||
TargetLowering &getTargetLoweringInfo() const { return TLI; }
|
||||
MachineDebugInfo *getMachineDebugInfo() const { return DI; }
|
||||
|
||||
/// viewGraph - Pop up a ghostview window with the DAG rendered using 'dot'.
|
||||
///
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||
#include "llvm/Support/Mangler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
@ -11,32 +11,35 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/DwarfWriter.h"
|
||||
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/DwarfWriter.h"
|
||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace llvm {
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool>
|
||||
DwarfVerbose("dwarf-verbose", cl::Hidden,
|
||||
cl::desc("Add comments to dwarf directives."));
|
||||
|
||||
/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
|
||||
/// unsigned leb128 value.
|
||||
/// unsigned leb128 value. Comment is added to the end of the directive if
|
||||
/// DwarfVerbose is true (should not contain any newlines.)
|
||||
///
|
||||
void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) {
|
||||
void DwarfWriter::EmitULEB128Bytes(unsigned Value, const char *Comment) const {
|
||||
if (hasLEB128) {
|
||||
O << "\t.uleb128\t"
|
||||
<< Value;
|
||||
} else {
|
||||
O << Asm->getData8bitsDirective();
|
||||
O << Asm->Data8bitsDirective;
|
||||
EmitULEB128(Value);
|
||||
}
|
||||
if (DwarfVerbose) {
|
||||
O << "\t"
|
||||
<< Asm->getCommentString()
|
||||
<< Asm->CommentString
|
||||
<< " "
|
||||
<< Comment
|
||||
<< " "
|
||||
@ -46,19 +49,20 @@ void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) {
|
||||
}
|
||||
|
||||
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
|
||||
/// signed leb128 value.
|
||||
/// signed leb128 value. Comment is added to the end of the directive if
|
||||
/// DwarfVerbose is true (should not contain any newlines.)
|
||||
///
|
||||
void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) {
|
||||
void DwarfWriter::EmitSLEB128Bytes(int Value, const char *Comment) const {
|
||||
if (hasLEB128) {
|
||||
O << "\t.sleb128\t"
|
||||
<< Value;
|
||||
} else {
|
||||
O << Asm->getData8bitsDirective();
|
||||
O << Asm->Data8bitsDirective;
|
||||
EmitSLEB128(Value);
|
||||
}
|
||||
if (DwarfVerbose) {
|
||||
O << "\t"
|
||||
<< Asm->getCommentString()
|
||||
<< Asm->CommentString
|
||||
<< " "
|
||||
<< Comment
|
||||
<< " "
|
||||
@ -67,13 +71,75 @@ void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) {
|
||||
O << "\n";
|
||||
}
|
||||
|
||||
/// BeginModule - Emit all dwarf sections that should come prior to the content.
|
||||
/// EmitHex - Emit a hexidecimal string to the output stream.
|
||||
///
|
||||
void DwarfWriter::BeginModule() {
|
||||
if (!DebugInfo.hasInfo()) return;
|
||||
EmitComment("Dwarf Begin Module");
|
||||
void DwarfWriter::EmitHex(unsigned Value) const {
|
||||
O << "0x"
|
||||
<< std::hex
|
||||
<< Value
|
||||
<< std::dec;
|
||||
}
|
||||
|
||||
/// EmitComment - Emit a simple string comment.
|
||||
///
|
||||
void DwarfWriter::EmitComment(const char *Comment) const {
|
||||
O << "\t"
|
||||
<< Asm->CommentString
|
||||
<< " "
|
||||
<< Comment
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
|
||||
/// representing an unsigned leb128 value.
|
||||
///
|
||||
void DwarfWriter::EmitULEB128(unsigned Value) const {
|
||||
do {
|
||||
unsigned Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
if (Value) Byte |= 0x80;
|
||||
EmitHex(Byte);
|
||||
if (Value) O << ", ";
|
||||
} while (Value);
|
||||
}
|
||||
|
||||
/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
|
||||
/// representing a signed leb128 value.
|
||||
///
|
||||
void DwarfWriter::EmitSLEB128(int Value) const {
|
||||
int Sign = Value >> (8 * sizeof(Value) - 1);
|
||||
bool IsMore;
|
||||
|
||||
// define base addresses for dwarf sections
|
||||
do {
|
||||
unsigned Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
|
||||
if (IsMore) Byte |= 0x80;
|
||||
EmitHex(Byte);
|
||||
if (IsMore) O << ", ";
|
||||
} while (IsMore);
|
||||
}
|
||||
|
||||
/// EmitLabelName - Emit label name for internal use by dwarf.
|
||||
///
|
||||
void DwarfWriter::EmitLabelName(const char *Tag, int Num) const {
|
||||
O << Asm->PrivateGlobalPrefix
|
||||
<< "debug_"
|
||||
<< Tag
|
||||
<< Num;
|
||||
}
|
||||
|
||||
/// EmitLabel - Emit location label for internal use by dwarf.
|
||||
///
|
||||
void DwarfWriter::EmitLabel(const char *Tag, int Num) const {
|
||||
EmitLabelName(Tag, Num);
|
||||
O << ":\n";
|
||||
}
|
||||
|
||||
/// EmitInitial -Emit initial dwarf declarations.
|
||||
///
|
||||
void DwarfWriter::EmitInitial() const {
|
||||
// Dwarf section's base addresses.
|
||||
Asm->SwitchSection(DwarfAbbrevSection, 0);
|
||||
EmitLabel("abbrev", 0);
|
||||
Asm->SwitchSection(DwarfInfoSection, 0);
|
||||
@ -82,33 +148,51 @@ void DwarfWriter::BeginModule() {
|
||||
EmitLabel("line", 0);
|
||||
}
|
||||
|
||||
/// ShouldEmitDwarf - Determine if dwarf declarations should be made.
|
||||
///
|
||||
bool DwarfWriter::ShouldEmitDwarf() {
|
||||
// Check if debug info is present.
|
||||
if (!DebugInfo || !DebugInfo->hasInfo()) return false;
|
||||
|
||||
// Make sure initial declarations are made.
|
||||
if (!didInitial) {
|
||||
EmitInitial();
|
||||
didInitial = true;
|
||||
}
|
||||
|
||||
// Okay to emit.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// BeginModule - Emit all dwarf sections that should come prior to the content.
|
||||
///
|
||||
void DwarfWriter::BeginModule() {
|
||||
if (!ShouldEmitDwarf()) return;
|
||||
EmitComment("Dwarf Begin Module");
|
||||
}
|
||||
|
||||
/// EndModule - Emit all dwarf sections that should come after the content.
|
||||
///
|
||||
void DwarfWriter::EndModule() {
|
||||
if (!DebugInfo.hasInfo()) return;
|
||||
if (!ShouldEmitDwarf()) return;
|
||||
EmitComment("Dwarf End Module");
|
||||
// Print out dwarf file info
|
||||
std::vector<std::string> Sources = DebugInfo.getSourceFiles();
|
||||
std::vector<std::string> Sources = DebugInfo->getSourceFiles();
|
||||
for (unsigned i = 0, N = Sources.size(); i < N; i++) {
|
||||
O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// BeginFunction - Emit pre-function debug information.
|
||||
///
|
||||
void DwarfWriter::BeginFunction() {
|
||||
if (!DebugInfo.hasInfo()) return;
|
||||
if (!ShouldEmitDwarf()) return;
|
||||
EmitComment("Dwarf Begin Function");
|
||||
}
|
||||
|
||||
/// EndFunction - Emit post-function debug information.
|
||||
///
|
||||
void DwarfWriter::EndFunction() {
|
||||
if (!DebugInfo.hasInfo()) return;
|
||||
if (!ShouldEmitDwarf()) return;
|
||||
EmitComment("Dwarf End Function");
|
||||
}
|
||||
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -18,74 +18,52 @@ using namespace llvm;
|
||||
|
||||
// Handle the Pass registration stuff necessary to use TargetData's.
|
||||
namespace {
|
||||
RegisterPass<MachineDebugInfo> X("machinedebuginfo", "Debug Information",
|
||||
PassInfo::Analysis | PassInfo::Optimization);
|
||||
RegisterPass<MachineDebugInfo> X("machinedebuginfo", "Debug Information");
|
||||
}
|
||||
|
||||
/// doInitialization - Initialize the debug state for a new module.
|
||||
///
|
||||
bool MachineDebugInfo::doInitialization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
/// doFinalization - Tear down the debug state after completion of a module.
|
||||
///
|
||||
bool MachineDebugInfo::doFinalization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getUniqueSourceID - Register a source file with debug info. Returns an id.
|
||||
///
|
||||
unsigned MachineDebugInfo::getUniqueSourceID(const std::string &fname,
|
||||
const std::string &dirname) {
|
||||
// Compose a key
|
||||
const std::string path = dirname + "/" + fname;
|
||||
// Check if the source file is already recorded
|
||||
std::map<std::string, unsigned>::iterator
|
||||
SMI = SourceMap.lower_bound(path);
|
||||
// If already there return existing id
|
||||
if (SMI != SourceMap.end() && SMI->first == path) return SMI->second;
|
||||
// Bump up the count
|
||||
++SourceCount;
|
||||
// Record the count
|
||||
SourceMap.insert(SMI, std::make_pair(path, SourceCount));
|
||||
// Return id
|
||||
return SourceCount;
|
||||
}
|
||||
|
||||
/// getSourceFiles - Return a vector of files. Vector index + 1 equals id.
|
||||
///
|
||||
std::vector<std::string> MachineDebugInfo::getSourceFiles() const {
|
||||
std::vector<std::string> Sources(SourceCount);
|
||||
|
||||
/// DebugInfo - Keep track of debug information for the function.
|
||||
///
|
||||
// FIXME - making it global until we can find a proper place to hang it from.
|
||||
MachineDebugInfo *DebugInfo;
|
||||
|
||||
// FIXME - temporary hack until we can find a place to hand debug info from.
|
||||
ModulePass *createDebugInfoPass() {
|
||||
if (!DebugInfo) DebugInfo = new MachineDebugInfo();
|
||||
return (ModulePass *)DebugInfo;
|
||||
}
|
||||
|
||||
/// getDebugInfo - Returns the DebugInfo.
|
||||
MachineDebugInfo &getMachineDebugInfo() {
|
||||
assert(DebugInfo && "DebugInfo pass not created");
|
||||
return *DebugInfo;
|
||||
for (std::map<std::string, unsigned>::const_iterator SMI = SourceMap.begin(),
|
||||
E = SourceMap.end();
|
||||
SMI != E; SMI++) {
|
||||
unsigned Index = SMI->second - 1;
|
||||
const std::string &Path = SMI->first;
|
||||
Sources[Index] = Path;
|
||||
}
|
||||
|
||||
/// doInitialization - Initialize the debug state for a new module.
|
||||
///
|
||||
bool MachineDebugInfo::doInitialization() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// doFinalization - Tear down the debug state after completion of a module.
|
||||
///
|
||||
bool MachineDebugInfo::doFinalization() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// RecordSource - Register a source file with debug info. Returns an id.
|
||||
///
|
||||
unsigned MachineDebugInfo::RecordSource(std::string fname,
|
||||
std::string dirname) {
|
||||
// Compose a key
|
||||
std::string path = dirname + "/" + fname;
|
||||
// Check if the source file is already recorded
|
||||
StrIntMapIter SMI = SourceMap.find(path);
|
||||
// If already there return existing id
|
||||
if (SMI != SourceMap.end()) return SMI->second;
|
||||
// Bump up the count
|
||||
++SourceCount;
|
||||
// Record the count
|
||||
SourceMap[path] = SourceCount;
|
||||
// Return id
|
||||
return SourceCount;
|
||||
}
|
||||
|
||||
/// getSourceFiles - Return a vector of files. Vector index + 1 equals id.
|
||||
///
|
||||
std::vector<std::string> MachineDebugInfo::getSourceFiles() {
|
||||
std::vector<std::string> Sources(SourceCount);
|
||||
|
||||
for (StrIntMapIter SMI = SourceMap.begin(), E = SourceMap.end(); SMI != E;
|
||||
SMI++) {
|
||||
unsigned Index = SMI->second - 1;
|
||||
std::string Path = SMI->first;
|
||||
Sources[Index] = Path;
|
||||
}
|
||||
return Sources;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
return Sources;
|
||||
}
|
||||
|
||||
|
@ -618,8 +618,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
case TargetLowering::Promote:
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Expand: {
|
||||
if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other)) {
|
||||
MachineDebugInfo &DebugInfo = getMachineDebugInfo();
|
||||
MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
|
||||
if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other) && DebugInfo) {
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Tmp1); // chain
|
||||
Ops.push_back(Node->getOperand(1)); // line #
|
||||
@ -628,9 +628,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
cast<StringSDNode>(Node->getOperand(3))->getValue();
|
||||
const std::string &dirname =
|
||||
cast<StringSDNode>(Node->getOperand(4))->getValue();
|
||||
unsigned srcfile = DebugInfo.RecordSource(fname, dirname);
|
||||
unsigned srcfile = DebugInfo->getUniqueSourceID(fname, dirname);
|
||||
Ops.push_back(DAG.getConstant(srcfile, MVT::i32)); // source file id
|
||||
unsigned id = DebugInfo.NextUniqueID();
|
||||
unsigned id = DebugInfo->getNextUniqueID();
|
||||
Ops.push_back(DAG.getConstant(id, MVT::i32)); // label id
|
||||
Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops);
|
||||
} else {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/CodeGen/IntrinsicLowering.h"
|
||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
@ -1640,7 +1641,7 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
|
||||
|
||||
void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
|
||||
FunctionLoweringInfo &FuncInfo) {
|
||||
SelectionDAG DAG(TLI, MF);
|
||||
SelectionDAG DAG(TLI, MF, getAnalysisToUpdate<MachineDebugInfo>());
|
||||
CurDAG = &DAG;
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
|
||||
|
||||
|
@ -204,16 +204,16 @@ namespace {
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &F) = 0;
|
||||
virtual bool doFinalization(Module &M) = 0;
|
||||
|
||||
};
|
||||
|
||||
/// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
|
||||
///
|
||||
struct DarwinDwarfWriter : public DwarfWriter {
|
||||
// Ctor.
|
||||
DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
|
||||
: DwarfWriter(o, ap, di)
|
||||
DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap)
|
||||
: DwarfWriter(o, ap)
|
||||
{
|
||||
hasLEB128 = false;
|
||||
needsSet = true;
|
||||
DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug";
|
||||
DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug";
|
||||
@ -229,9 +229,7 @@ namespace {
|
||||
DarwinDwarfWriter DW;
|
||||
|
||||
DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
|
||||
: PPCAsmPrinter(O, TM),
|
||||
// FIXME - MachineDebugInfo needs a proper location
|
||||
DW(O, this, getMachineDebugInfo())
|
||||
: PPCAsmPrinter(O, TM), DW(O, this)
|
||||
{
|
||||
CommentString = ";";
|
||||
GlobalPrefix = "_";
|
||||
@ -252,6 +250,11 @@ namespace {
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
bool doInitialization(Module &M);
|
||||
bool doFinalization(Module &M);
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<MachineDebugInfo>();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
|
||||
@ -483,6 +486,7 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
|
||||
Mang->setUseQuotes(true);
|
||||
|
||||
// Emit initial debug information.
|
||||
DW.SetDebugInfo(getAnalysisToUpdate<MachineDebugInfo>());
|
||||
DW.BeginModule();
|
||||
return false;
|
||||
}
|
||||
@ -613,7 +617,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
|
||||
return false; // success
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - This uses the printMachineInstruction()
|
||||
/// runOnMachineFunction - This uses the e()
|
||||
/// method to print assembly for each instruction.
|
||||
///
|
||||
bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
@ -239,9 +239,6 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set up collection of debug information
|
||||
Passes.add(createDebugInfoPass());
|
||||
|
||||
// Ask the target to add backend passes as necessary.
|
||||
if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
|
||||
std::cerr << argv[0] << ": target '" << Target.getName()
|
||||
|
Loading…
x
Reference in New Issue
Block a user