Skip to content

Commit

Permalink
Add CFI directives-based frame information emission. Not hooked yet.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123474 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
asl committed Jan 14, 2011
1 parent d7e8ddc commit 9a1ef4e
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 1 deletion.
2 changes: 1 addition & 1 deletion include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ namespace llvm {
/// frame.
void EmitFrameMoves(const std::vector<MachineMove> &Moves,
MCSymbol *BaseLabel, bool isEH) const;

void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const;

//===------------------------------------------------------------------===//
// Inline Asm Support
Expand Down
40 changes: 40 additions & 0 deletions lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,43 @@ void AsmPrinter::EmitFrameMoves(const std::vector<MachineMove> &Moves,
}
}
}

/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void AsmPrinter::EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const {
const TargetRegisterInfo *RI = TM.getRegisterInfo();

int stackGrowth = TM.getTargetData()->getPointerSize();
if (TM.getFrameLowering()->getStackGrowthDirection() !=
TargetFrameLowering::StackGrowsUp)
stackGrowth *= -1;

for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
const MachineMove &Move = Moves[i];
MCSymbol *Label = Move.getLabel();
// Throw out move if the label is invalid.
if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.

const MachineLocation &Dst = Move.getDestination();
const MachineLocation &Src = Move.getSource();

// If advancing cfa.
if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
assert(!Src.isReg() && "Machine move not supported yet.");

if (Src.getReg() == MachineLocation::VirtualFP) {
OutStreamer.EmitCFIDefCfaOffset(-Src.getOffset());
} else {
assert("Machine move not supported yet");
// Reg + Offset
}
} else if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
assert(Dst.isReg() && "Machine move not supported yet.");
OutStreamer.EmitCFIDefCfaRegister(RI->getDwarfRegNum(Dst.getReg(), true));
} else {
assert(!Dst.isReg() && "Machine move not supported yet.");
OutStreamer.EmitCFIOffset(RI->getDwarfRegNum(Src.getReg(), true),
Dst.getOffset());
}
}
}
138 changes: 138 additions & 0 deletions lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing DWARF exception info into asm files.
//
//===----------------------------------------------------------------------===//

#include "DwarfException.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#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"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;

DwarfCFIException::DwarfCFIException(AsmPrinter *A)
: DwarfException(A),
shouldEmitTable(false), shouldEmitMoves(false), shouldEmitTableModule(false)
{}

DwarfCFIException::~DwarfCFIException() {}

/// EndModule - Emit all exception information that should come after the
/// content.
void DwarfCFIException::EndModule() {
if (Asm->MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
return;

if (!shouldEmitTableModule)
return;

const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();

// Begin eh frame section.
Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());

// Emit references to all used personality functions
const std::vector<const Function*> &Personalities = MMI->getPersonalities();
for (size_t i = 0, e = Personalities.size(); i != e; ++i) {
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("personality", i));
Asm->EmitReference(Personalities[i], PerEncoding);
}
}

/// BeginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void DwarfCFIException::BeginFunction(const MachineFunction *MF) {
shouldEmitTable = shouldEmitMoves = false;

// If any landing pads survive, we need an EH table.
shouldEmitTable = !MMI->getLandingPads().empty();

// See if we need frame move info.
shouldEmitMoves =
!Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;

if (shouldEmitMoves || shouldEmitTable)
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
Asm->getFunctionNumber()));

shouldEmitTableModule |= shouldEmitTable;

if (shouldEmitMoves) {
const TargetFrameLowering *TFL = Asm->TM.getFrameLowering();
Asm->OutStreamer.EmitCFIStartProc();

// Indicate locations of general callee saved registers in frame.
std::vector<MachineMove> Moves;
TFL->getInitialFrameState(Moves);
Asm->EmitCFIFrameMoves(Moves);
Asm->EmitCFIFrameMoves(MMI->getFrameMoves());
}

if (!shouldEmitTable)
return;

const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();

// Provide LSDA information.
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
if (LSDAEncoding != dwarf::DW_EH_PE_omit)
Asm->OutStreamer.EmitCFILsda(Asm->GetTempSymbol("exception",
Asm->getFunctionNumber()),
LSDAEncoding);

// Indicate personality routine, if any.
unsigned PerEncoding = TLOF.getPersonalityEncoding();
if (PerEncoding != dwarf::DW_EH_PE_omit &&
MMI->getPersonalities()[MMI->getPersonalityIndex()])
Asm->OutStreamer.EmitCFIPersonality(Asm->GetTempSymbol("personality",
MMI->getPersonalityIndex()),
PerEncoding);
}

/// EndFunction - Gather and emit post-function exception information.
///
void DwarfCFIException::EndFunction() {
if (!shouldEmitMoves && !shouldEmitTable) return;

if (shouldEmitMoves)
Asm->OutStreamer.EmitCFIEndProc();

Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));

// Map all labels and get rid of any dead landing pads.
MMI->TidyLandingPads();

if (shouldEmitTable)
EmitExceptionTable();
}
31 changes: 31 additions & 0 deletions lib/CodeGen/AsmPrinter/DwarfException.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,37 @@ class DwarfException {
virtual void EndFunction();
};

class DwarfCFIException : public DwarfException {
/// shouldEmitTable - Per-function flag to indicate if EH tables should
/// be emitted.
bool shouldEmitTable;

/// shouldEmitMoves - Per-function flag to indicate if frame moves info
/// should be emitted.
bool shouldEmitMoves;

/// shouldEmitTableModule - Per-module flag to indicate if EH tables
/// should be emitted.
bool shouldEmitTableModule;
public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
DwarfCFIException(AsmPrinter *A);
virtual ~DwarfCFIException();

/// EndModule - Emit all exception information that should come after the
/// content.
virtual void EndModule();

/// BeginFunction - Gather pre-function exception information. Assumes being
/// emitted immediately after the function entry point.
virtual void BeginFunction(const MachineFunction *MF);

/// EndFunction - Gather and emit post-function exception information.
virtual void EndFunction();
};

class DwarfTableException : public DwarfException {
/// shouldEmitTable - Per-function flag to indicate if EH tables should
/// be emitted.
Expand Down

0 comments on commit 9a1ef4e

Please sign in to comment.