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

Generated by: LCOV version 1.13