LCOV - code coverage report
Current view: top level - include/llvm/MC - MCLinkerOptimizationHint.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 40 97.5 %
Date: 2017-09-14 15:23:50 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
       2             : //
       3             : //
       4             : //                     The LLVM Compiler Infrastructure
       5             : //
       6             : // This file is distributed under the University of Illinois Open Source
       7             : // License. See LICENSE.TXT for details.
       8             : //
       9             : //===----------------------------------------------------------------------===//
      10             : //
      11             : // This file declares some helpers classes to handle Linker Optimization Hint
      12             : // (LOH).
      13             : //
      14             : // FIXME: LOH interface supports only MachO format at the moment.
      15             : //===----------------------------------------------------------------------===//
      16             : 
      17             : #ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
      18             : #define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
      19             : 
      20             : #include "llvm/ADT/SmallVector.h"
      21             : #include "llvm/ADT/StringRef.h"
      22             : #include "llvm/ADT/StringSwitch.h"
      23             : #include "llvm/Support/raw_ostream.h"
      24             : #include <cassert>
      25             : #include <cstdint>
      26             : 
      27             : namespace llvm {
      28             : 
      29             : class MachObjectWriter;
      30             : class MCAsmLayout;
      31             : class MCSymbol;
      32             : 
      33             : /// Linker Optimization Hint Type.
      34             : enum MCLOHType {
      35             :   MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
      36             :   MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
      37             :   MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
      38             :   MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
      39             :   MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
      40             :   MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
      41             :   MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
      42             :   MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
      43             : };
      44             : 
      45             : static inline StringRef MCLOHDirectiveName() {
      46         426 :   return StringRef(".loh");
      47             : }
      48             : 
      49             : static inline bool isValidMCLOHType(unsigned Kind) {
      50          11 :   return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
      51             : }
      52             : 
      53          12 : static inline int MCLOHNameToId(StringRef Name) {
      54             : #define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)
      55          12 :   return StringSwitch<int>(Name)
      56          36 :     MCLOHCaseNameToId(AdrpAdrp)
      57          36 :     MCLOHCaseNameToId(AdrpLdr)
      58          36 :     MCLOHCaseNameToId(AdrpAddLdr)
      59          36 :     MCLOHCaseNameToId(AdrpLdrGotLdr)
      60          36 :     MCLOHCaseNameToId(AdrpAddStr)
      61          36 :     MCLOHCaseNameToId(AdrpLdrGotStr)
      62          36 :     MCLOHCaseNameToId(AdrpAdd)
      63          36 :     MCLOHCaseNameToId(AdrpLdrGot)
      64          36 :     .Default(-1);
      65             : }
      66             : 
      67         227 : static inline StringRef MCLOHIdToName(MCLOHType Kind) {
      68             : #define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);
      69         227 :   switch (Kind) {
      70          13 :     MCLOHCaseIdToName(AdrpAdrp);
      71          60 :     MCLOHCaseIdToName(AdrpLdr);
      72           4 :     MCLOHCaseIdToName(AdrpAddLdr);
      73          39 :     MCLOHCaseIdToName(AdrpLdrGotLdr);
      74           4 :     MCLOHCaseIdToName(AdrpAddStr);
      75          15 :     MCLOHCaseIdToName(AdrpLdrGotStr);
      76          22 :     MCLOHCaseIdToName(AdrpAdd);
      77          70 :     MCLOHCaseIdToName(AdrpLdrGot);
      78             :   }
      79           0 :   return StringRef();
      80             : }
      81             : 
      82             : static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
      83             :   switch (Kind) {
      84             :     // LOH with two arguments
      85             :   case MCLOH_AdrpAdrp:
      86             :   case MCLOH_AdrpLdr:
      87             :   case MCLOH_AdrpAdd:
      88             :   case MCLOH_AdrpLdrGot:
      89             :     return 2;
      90             :     // LOH with three arguments
      91             :   case MCLOH_AdrpAddLdr:
      92             :   case MCLOH_AdrpLdrGotLdr:
      93             :   case MCLOH_AdrpAddStr:
      94             :   case MCLOH_AdrpLdrGotStr:
      95             :     return 3;
      96             :   }
      97             :   return -1;
      98             : }
      99             : 
     100             : /// Store Linker Optimization Hint information (LOH).
     101           5 : class MCLOHDirective {
     102             :   MCLOHType Kind;
     103             : 
     104             :   /// Arguments of this directive. Order matters.
     105             :   SmallVector<MCSymbol *, 3> Args;
     106             : 
     107             :   /// Emit this directive in \p OutStream using the information available
     108             :   /// in the given \p ObjWriter and \p Layout to get the address of the
     109             :   /// arguments within the object file.
     110             :   void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
     111             :                  const MCAsmLayout &Layout) const;
     112             : 
     113             : public:
     114             :   using LOHArgs = SmallVectorImpl<MCSymbol *>;
     115             : 
     116             :   MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
     117           4 :       : Kind(Kind), Args(Args.begin(), Args.end()) {
     118             :     assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
     119             :   }
     120             : 
     121             :   MCLOHType getKind() const { return Kind; }
     122             : 
     123             :   const LOHArgs &getArgs() const { return Args; }
     124             : 
     125             :   /// Emit this directive as:
     126             :   /// <kind, numArgs, addr1, ..., addrN>
     127             :   void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const;
     128             : 
     129             :   /// Get the size in bytes of this directive if emitted in \p ObjWriter with
     130             :   /// the given \p Layout.
     131             :   uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
     132             :                        const MCAsmLayout &Layout) const;
     133             : };
     134             : 
     135        8242 : class MCLOHContainer {
     136             :   /// Keep track of the emit size of all the LOHs.
     137             :   mutable uint64_t EmitSize = 0;
     138             : 
     139             :   /// Keep track of all LOH directives.
     140             :   SmallVector<MCLOHDirective, 32> Directives;
     141             : 
     142             : public:
     143             :   using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
     144             : 
     145        8294 :   MCLOHContainer() = default;
     146             : 
     147             :   /// Const accessor to the directives.
     148             :   const LOHDirectives &getDirectives() const {
     149             :     return Directives;
     150             :   }
     151             : 
     152             :   /// Add the directive of the given kind \p Kind with the given arguments
     153             :   /// \p Args to the container.
     154           1 :   void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
     155           3 :     Directives.push_back(MCLOHDirective(Kind, Args));
     156           1 :   }
     157             : 
     158             :   /// Get the size of the directives if emitted.
     159         498 :   uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
     160             :                        const MCAsmLayout &Layout) const {
     161         498 :     if (!EmitSize) {
     162        1495 :       for (const MCLOHDirective &D : Directives)
     163           1 :         EmitSize += D.getEmitSize(ObjWriter, Layout);
     164             :     }
     165         498 :     return EmitSize;
     166             :   }
     167             : 
     168             :   /// Emit all Linker Optimization Hint in one big table.
     169             :   /// Each line of the table is emitted by LOHDirective::emit.
     170             :   void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
     171           4 :     for (const MCLOHDirective &D : Directives)
     172           1 :       D.emit(ObjWriter, Layout);
     173             :   }
     174             : 
     175             :   void reset() {
     176        3163 :     Directives.clear();
     177        3163 :     EmitSize = 0;
     178             :   }
     179             : };
     180             : 
     181             : // Add types for specialized template using MCSymbol.
     182             : using MCLOHArgs = MCLOHDirective::LOHArgs;
     183             : using MCLOHDirectives = MCLOHContainer::LOHDirectives;
     184             : 
     185             : } // end namespace llvm
     186             : 
     187             : #endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H

Generated by: LCOV version 1.13