[MC] Attach labels to existing fragments instead of using a separate fragment

Summary:
Currently when emitting a label, a new data fragment is created for it if the
current fragment isn't a data fragment.
This change instead enqueues the label and attaches it to the next fragment
(e.g. created for the next instruction) if possible.

When bundle alignment is not enabled, this has no functionality change (it
just results in fewer extra fragments being created). For bundle alignment,
previously labels would point to the beginning of the bundle padding instead
of the beginning of the emitted instruction. This was not only less efficient
(e.g. jumping to the nops instead of past them) but also led to miscalculation
of the address of the GOT (since MC uses a label difference rather than
emitting a "." symbol).

Fixes https://code.google.com/p/nativeclient/issues/detail?id=3982

Test Plan: regression test attached

Reviewers: jvoung, eliben

Subscribers: jfb, llvm-commits

Differential Revision: http://reviews.llvm.org/D5915

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Derek Schuff
2014-10-22 22:38:06 +00:00
parent 545127f54d
commit cdb105b62f
4 changed files with 122 additions and 12 deletions

View File

@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCOBJECTSTREAMER_H
#define LLVM_MC_MCOBJECTSTREAMER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCStreamer.h"
@@ -37,11 +38,16 @@ class MCObjectStreamer : public MCStreamer {
MCSectionData::iterator CurInsertionPoint;
bool EmitEHFrame;
bool EmitDebugFrame;
SmallVector<MCSymbolData *, 2> PendingLabels;
virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
// If any labels have been emitted but not assigned fragments, ensure that
// they get assigned, either to F if possible or to a new data fragment.
void flushPendingLabels(MCFragment *F);
protected:
MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
MCCodeEmitter *_Emitter);
@@ -69,14 +75,15 @@ protected:
MCFragment *getCurrentFragment() const;
void insert(MCFragment *F) const {
void insert(MCFragment *F) {
flushPendingLabels(F);
CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
F->setParent(CurSectionData);
}
/// Get a data fragment to write into, creating a new one if the current
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment() const;
MCDataFragment *getOrCreateDataFragment();
public:
void visitUsedSymbol(const MCSymbol &Sym) override;