LCOV - code coverage report
Current view: top level - lib/CodeGen - MachineModuleInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 86 110 78.2 %
Date: 2018-09-23 13:06:45 Functions: 21 26 80.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/CodeGen/MachineModuleInfo.h"
      11             : #include "llvm/ADT/ArrayRef.h"
      12             : #include "llvm/ADT/DenseMap.h"
      13             : #include "llvm/ADT/PostOrderIterator.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/ADT/TinyPtrVector.h"
      16             : #include "llvm/CodeGen/MachineFunction.h"
      17             : #include "llvm/CodeGen/Passes.h"
      18             : #include "llvm/IR/BasicBlock.h"
      19             : #include "llvm/IR/DerivedTypes.h"
      20             : #include "llvm/IR/Instructions.h"
      21             : #include "llvm/IR/Module.h"
      22             : #include "llvm/IR/Value.h"
      23             : #include "llvm/IR/ValueHandle.h"
      24             : #include "llvm/MC/MCContext.h"
      25             : #include "llvm/MC/MCSymbol.h"
      26             : #include "llvm/Pass.h"
      27             : #include "llvm/Support/Casting.h"
      28             : #include "llvm/Support/ErrorHandling.h"
      29             : #include "llvm/Target/TargetLoweringObjectFile.h"
      30             : #include "llvm/Target/TargetMachine.h"
      31             : #include <algorithm>
      32             : #include <cassert>
      33             : #include <memory>
      34             : #include <utility>
      35             : #include <vector>
      36             : 
      37             : using namespace llvm;
      38             : using namespace llvm::dwarf;
      39             : 
      40             : // Handle the Pass registration stuff necessary to use DataLayout's.
      41      116506 : INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
      42             :                 "Machine Module Information", false, false)
      43             : char MachineModuleInfo::ID = 0;
      44             : 
      45             : // Out of line virtual method.
      46             : MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
      47             : 
      48             : namespace llvm {
      49             : 
      50        1346 : class MMIAddrLabelMapCallbackPtr final : CallbackVH {
      51             :   MMIAddrLabelMap *Map = nullptr;
      52             : 
      53             : public:
      54             :   MMIAddrLabelMapCallbackPtr() = default;
      55         533 :   MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}
      56             : 
      57             :   void setPtr(BasicBlock *BB) {
      58           0 :     ValueHandleBase::operator=(BB);
      59             :   }
      60             : 
      61         533 :   void setMap(MMIAddrLabelMap *map) { Map = map; }
      62             : 
      63             :   void deleted() override;
      64             :   void allUsesReplacedWith(Value *V2) override;
      65             : };
      66             : 
      67             : class MMIAddrLabelMap {
      68             :   MCContext &Context;
      69         532 :   struct AddrLabelSymEntry {
      70             :     /// The symbols for the label.
      71             :     TinyPtrVector<MCSymbol *> Symbols;
      72             : 
      73             :     Function *Fn;   // The containing function of the BasicBlock.
      74             :     unsigned Index; // The index in BBCallbacks for the BasicBlock.
      75             :   };
      76             : 
      77             :   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
      78             : 
      79             :   /// Callbacks for the BasicBlock's that we have entries for.  We use this so
      80             :   /// we get notified if a block is deleted or RAUWd.
      81             :   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
      82             : 
      83             :   /// This is a per-function list of symbols whose corresponding BasicBlock got
      84             :   /// deleted.  These symbols need to be emitted at some point in the file, so
      85             :   /// AsmPrinter emits them after the function body.
      86             :   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>
      87             :     DeletedAddrLabelsNeedingEmission;
      88             : 
      89             : public:
      90         236 :   MMIAddrLabelMap(MCContext &context) : Context(context) {}
      91             : 
      92         470 :   ~MMIAddrLabelMap() {
      93             :     assert(DeletedAddrLabelsNeedingEmission.empty() &&
      94             :            "Some labels for deleted blocks never got emitted");
      95         235 :   }
      96             : 
      97             :   ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
      98             : 
      99             :   void takeDeletedSymbolsForFunction(Function *F,
     100             :                                      std::vector<MCSymbol*> &Result);
     101             : 
     102             :   void UpdateForDeletedBlock(BasicBlock *BB);
     103             :   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
     104             : };
     105             : 
     106             : } // end namespace llvm
     107             : 
     108        1292 : ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
     109             :   assert(BB->hasAddressTaken() &&
     110             :          "Shouldn't get label for block without address taken");
     111        2584 :   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
     112             : 
     113             :   // If we already had an entry for this block, just return it.
     114           0 :   if (!Entry.Symbols.empty()) {
     115             :     assert(BB->getParent() == Entry.Fn && "Parent changed");
     116         759 :     return Entry.Symbols;
     117             :   }
     118             : 
     119             :   // Otherwise, this is a new entry, create a new symbol for it and add an
     120             :   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
     121         533 :   BBCallbacks.emplace_back(BB);
     122             :   BBCallbacks.back().setMap(this);
     123         533 :   Entry.Index = BBCallbacks.size() - 1;
     124         533 :   Entry.Fn = BB->getParent();
     125         533 :   Entry.Symbols.push_back(Context.createTempSymbol());
     126         533 :   return Entry.Symbols;
     127             : }
     128             : 
     129             : /// If we have any deleted symbols for F, return them.
     130         146 : void MMIAddrLabelMap::
     131             : takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
     132             :   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I =
     133         292 :     DeletedAddrLabelsNeedingEmission.find(F);
     134             : 
     135             :   // If there are no entries for the function, just return.
     136         146 :   if (I == DeletedAddrLabelsNeedingEmission.end()) return;
     137             : 
     138             :   // Otherwise, take the list.
     139             :   std::swap(Result, I->second);
     140             :   DeletedAddrLabelsNeedingEmission.erase(I);
     141             : }
     142             : 
     143           0 : void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
     144             :   // If the block got deleted, there is no need for the symbol.  If the symbol
     145             :   // was already emitted, we can just forget about it, otherwise we need to
     146             :   // queue it up for later emission when the function is output.
     147           0 :   AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
     148           0 :   AddrLabelSymbols.erase(BB);
     149             :   assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
     150           0 :   BBCallbacks[Entry.Index] = nullptr;  // Clear the callback.
     151             : 
     152             :   assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
     153             :          "Block/parent mismatch");
     154             : 
     155           0 :   for (MCSymbol *Sym : Entry.Symbols) {
     156           0 :     if (Sym->isDefined())
     157           0 :       return;
     158             : 
     159             :     // If the block is not yet defined, we need to emit it at the end of the
     160             :     // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
     161             :     // for the containing Function.  Since the block is being deleted, its
     162             :     // parent may already be removed, we have to get the function from 'Entry'.
     163           0 :     DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
     164             :   }
     165             : }
     166             : 
     167           0 : void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
     168             :   // Get the entry for the RAUW'd block and remove it from our map.
     169           0 :   AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
     170           0 :   AddrLabelSymbols.erase(Old);
     171             :   assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
     172             : 
     173           0 :   AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
     174             : 
     175             :   // If New is not address taken, just move our symbol over to it.
     176           0 :   if (NewEntry.Symbols.empty()) {
     177           0 :     BBCallbacks[OldEntry.Index].setPtr(New);    // Update the callback.
     178             :     NewEntry = std::move(OldEntry);             // Set New's entry.
     179             :     return;
     180             :   }
     181             : 
     182           0 :   BBCallbacks[OldEntry.Index] = nullptr;    // Update the callback.
     183             : 
     184             :   // Otherwise, we need to add the old symbols to the new block's set.
     185           0 :   NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(),
     186             :                           OldEntry.Symbols.end());
     187             : }
     188             : 
     189           0 : void MMIAddrLabelMapCallbackPtr::deleted() {
     190           0 :   Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
     191           0 : }
     192             : 
     193           0 : void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
     194           0 :   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
     195           0 : }
     196             : 
     197       29607 : MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
     198             :   : ImmutablePass(ID), TM(*TM),
     199             :     Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
     200       29607 :             TM->getObjFileLowering(), nullptr, false) {
     201       29607 :   initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
     202       29607 : }
     203             : 
     204             : MachineModuleInfo::~MachineModuleInfo() = default;
     205             : 
     206       29406 : bool MachineModuleInfo::doInitialization(Module &M) {
     207       29406 :   ObjFileMMI = nullptr;
     208       29406 :   CurCallSite = 0;
     209       29406 :   DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
     210       29406 :   HasSplitStack = HasNosplitStack = false;
     211       29406 :   AddrLabelSymbols = nullptr;
     212       29406 :   TheModule = &M;
     213       29406 :   return false;
     214             : }
     215             : 
     216       29256 : bool MachineModuleInfo::doFinalization(Module &M) {
     217             :   Personalities.clear();
     218             : 
     219       29256 :   delete AddrLabelSymbols;
     220       29256 :   AddrLabelSymbols = nullptr;
     221             : 
     222       29256 :   Context.reset();
     223             : 
     224       29256 :   delete ObjFileMMI;
     225       29256 :   ObjFileMMI = nullptr;
     226             : 
     227       29256 :   return false;
     228             : }
     229             : 
     230             : //===- Address of Block Management ----------------------------------------===//
     231             : 
     232             : ArrayRef<MCSymbol *>
     233        1292 : MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
     234             :   // Lazily create AddrLabelSymbols.
     235        1292 :   if (!AddrLabelSymbols)
     236         236 :     AddrLabelSymbols = new MMIAddrLabelMap(Context);
     237        1292 :  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
     238             : }
     239             : 
     240      428805 : void MachineModuleInfo::
     241             : takeDeletedSymbolsForFunction(const Function *F,
     242             :                               std::vector<MCSymbol*> &Result) {
     243             :   // If no blocks have had their addresses taken, we're done.
     244      428805 :   if (!AddrLabelSymbols) return;
     245             :   return AddrLabelSymbols->
     246         146 :      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
     247             : }
     248             : 
     249             : /// \name Exception Handling
     250             : /// \{
     251             : 
     252      343037 : void MachineModuleInfo::addPersonality(const Function *Personality) {
     253      686082 :   for (unsigned i = 0; i < Personalities.size(); ++i)
     254      339430 :     if (Personalities[i] == Personality)
     255             :       return;
     256        3615 :   Personalities.push_back(Personality);
     257             : }
     258             : 
     259             : /// \}
     260             : 
     261             : MachineFunction *
     262       18259 : MachineModuleInfo::getMachineFunction(const Function &F) const {
     263       18259 :   auto I = MachineFunctions.find(&F);
     264       18259 :   return I != MachineFunctions.end() ? I->second.get() : nullptr;
     265             : }
     266             : 
     267             : MachineFunction &
     268    28694754 : MachineModuleInfo::getOrCreateMachineFunction(const Function &F) {
     269             :   // Shortcut for the common case where a sequence of MachineFunctionPasses
     270             :   // all query for the same Function.
     271    28694754 :   if (LastRequest == &F)
     272    28243846 :     return *LastResult;
     273             : 
     274      450908 :   auto I = MachineFunctions.insert(
     275      450908 :       std::make_pair(&F, std::unique_ptr<MachineFunction>()));
     276             :   MachineFunction *MF;
     277      450908 :   if (I.second) {
     278             :     // No pre-existing machine function, create a new one.
     279      433746 :     const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F);
     280      433746 :     MF = new MachineFunction(F, TM, STI, NextFnNum++, *this);
     281             :     // Update the set entry.
     282             :     I.first->second.reset(MF);
     283             :   } else {
     284             :     MF = I.first->second.get();
     285             :   }
     286             : 
     287      450908 :   LastRequest = &F;
     288      450908 :   LastResult = MF;
     289      450908 :   return *MF;
     290             : }
     291             : 
     292      433456 : void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
     293      433456 :   MachineFunctions.erase(&F);
     294      433456 :   LastRequest = nullptr;
     295      433456 :   LastResult = nullptr;
     296      433456 : }
     297             : 
     298             : namespace {
     299             : 
     300             : /// This pass frees the MachineFunction object associated with a Function.
     301             : class FreeMachineFunction : public FunctionPass {
     302             : public:
     303             :   static char ID;
     304             : 
     305       29537 :   FreeMachineFunction() : FunctionPass(ID) {}
     306             : 
     307       29537 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
     308             :     AU.addRequired<MachineModuleInfo>();
     309             :     AU.addPreserved<MachineModuleInfo>();
     310       29537 :   }
     311             : 
     312      433456 :   bool runOnFunction(Function &F) override {
     313      433456 :     MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
     314      433456 :     MMI.deleteMachineFunctionFor(F);
     315      433456 :     return true;
     316             :   }
     317             : 
     318          18 :   StringRef getPassName() const override {
     319          18 :     return "Free MachineFunction";
     320             :   }
     321             : };
     322             : 
     323             : } // end anonymous namespace
     324             : 
     325             : char FreeMachineFunction::ID;
     326             : 
     327       29537 : FunctionPass *llvm::createFreeMachineFunctionPass() {
     328       29537 :   return new FreeMachineFunction();
     329             : }
     330             : 
     331             : //===- MMI building helpers -----------------------------------------------===//
     332             : 
     333     2541544 : void llvm::computeUsesVAFloatArgument(const CallInst &I,
     334             :                                       MachineModuleInfo &MMI) {
     335             :   FunctionType *FT =
     336     2541544 :       cast<FunctionType>(I.getCalledValue()->getType()->getContainedType(0));
     337     2541544 :   if (FT->isVarArg() && !MMI.usesVAFloatArgument()) {
     338       63206 :     for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
     339       28857 :       Type *T = I.getArgOperand(i)->getType();
     340      132840 :       for (auto i : post_order(T)) {
     341             :         if (i->isFloatingPointTy()) {
     342             :           MMI.setUsesVAFloatArgument(true);
     343         145 :           return;
     344             :         }
     345             :       }
     346             :     }
     347             :   }
     348             : }

Generated by: LCOV version 1.13