ARM/ELF: Better codegen for global variable addresses.
[oota-llvm.git] / include / llvm / MC / MCELFStreamer.h
index ebd5d57651180beae465c9dbc6da05d215bbff4c..2f3d49e3aca5f3feae390d96e3e49f7532430d72 100644 (file)
@@ -23,32 +23,30 @@ class MCAssembler;
 class MCCodeEmitter;
 class MCExpr;
 class MCInst;
-class MCSymbol;
-class MCSymbolData;
 class raw_ostream;
 
 class MCELFStreamer : public MCObjectStreamer {
 public:
-  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
                 MCCodeEmitter *Emitter)
-      : MCObjectStreamer(Context, TAB, OS, Emitter),
-        SeenIdent(false) {}
+      : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
 
-  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
-                MCCodeEmitter *Emitter, MCAssembler *Assembler)
-      : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
-        SeenIdent(false) {}
+  ~MCELFStreamer() override;
 
-  virtual ~MCELFStreamer();
+  /// state management
+  void reset() override {
+    SeenIdent = false;
+    LocalCommons.clear();
+    BundleGroups.clear();
+    MCObjectStreamer::reset();
+  }
 
-  /// @name MCStreamer Interface
+  /// \name MCStreamer Interface
   /// @{
 
-  void InitSections() override;
-  void ChangeSection(const MCSection *Section,
-                     const MCExpr *Subsection) override;
+  void InitSections(bool NoExecStack) override;
+  void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
   void EmitLabel(MCSymbol *Symbol) override;
-  void EmitDebugLabel(MCSymbol *Symbol) override;
   void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
   void EmitThumbFunc(MCSymbol *Func) override;
   void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
@@ -61,18 +59,17 @@ public:
   void EmitCOFFSymbolType(int Type) override;
   void EndCOFFSymbolDef() override;
 
-  MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override;
-
-  void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+  void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override;
 
   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                              unsigned ByteAlignment) override;
 
-  void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+  void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
                     uint64_t Size = 0, unsigned ByteAlignment = 0) override;
-  void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
-                      uint64_t Size, unsigned ByteAlignment = 0) override;
-  void EmitValueImpl(const MCExpr *Value, unsigned Size) override;
+  void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+                      unsigned ByteAlignment = 0) override;
+  void EmitValueImpl(const MCExpr *Value, unsigned Size,
+                     SMLoc Loc = SMLoc()) override;
 
   void EmitFileDirective(StringRef Filename) override;
 
@@ -89,27 +86,33 @@ public:
   void EmitBundleUnlock() override;
 
 private:
+  bool isBundleLocked() const;
   void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
   void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
 
   void fixSymbolsInTLSFixups(const MCExpr *expr);
 
+  /// \brief Merge the content of the fragment \p EF into the fragment \p DF.
+  void mergeFragment(MCDataFragment *, MCDataFragment *);
+
   bool SeenIdent;
 
   struct LocalCommon {
-    MCSymbolData *SD;
+    const MCSymbol *Symbol;
     uint64_t Size;
     unsigned ByteAlignment;
   };
 
   std::vector<LocalCommon> LocalCommons;
 
-  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+  /// BundleGroups - The stack of fragments holding the bundle-locked
+  /// instructions.
+  llvm::SmallVector<MCDataFragment *, 4> BundleGroups;
 };
 
 MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
-                                    raw_ostream &OS, MCCodeEmitter *Emitter,
-                                    bool RelaxAll, bool NoExecStack,
+                                    raw_pwrite_stream &OS,
+                                    MCCodeEmitter *Emitter, bool RelaxAll,
                                     bool IsThumb);
 
 } // end namespace llvm