brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · a669877 Raw
206 lines · cpp
1//===-- MachineFunctionPass.cpp -------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the definitions of the MachineFunctionPass members.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/MachineFunctionPass.h"14#include "llvm/Analysis/BasicAliasAnalysis.h"15#include "llvm/Analysis/DominanceFrontier.h"16#include "llvm/Analysis/GlobalsModRef.h"17#include "llvm/Analysis/IVUsers.h"18#include "llvm/Analysis/LoopInfo.h"19#include "llvm/Analysis/MemoryDependenceAnalysis.h"20#include "llvm/Analysis/OptimizationRemarkEmitter.h"21#include "llvm/Analysis/ScalarEvolution.h"22#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"23#include "llvm/CodeGen/DroppedVariableStatsMIR.h"24#include "llvm/CodeGen/MachineFunction.h"25#include "llvm/CodeGen/MachineModuleInfo.h"26#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"27#include "llvm/CodeGen/Passes.h"28#include "llvm/IR/Dominators.h"29#include "llvm/IR/Function.h"30#include "llvm/IR/Module.h"31#include "llvm/IR/PrintPasses.h"32 33using namespace llvm;34using namespace ore;35 36static cl::opt<bool> DroppedVarStatsMIR(37    "dropped-variable-stats-mir", cl::Hidden,38    cl::desc("Dump dropped debug variables stats for MIR passes"),39    cl::init(false));40 41Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,42                                             const std::string &Banner) const {43  return createMachineFunctionPrinterPass(O, Banner);44}45 46bool MachineFunctionPass::runOnFunction(Function &F) {47  // Do not codegen any 'available_externally' functions at all, they have48  // definitions outside the translation unit.49  if (F.hasAvailableExternallyLinkage())50    return false;51 52  MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();53  MachineFunction &MF = MMI.getOrCreateMachineFunction(F);54 55  MachineFunctionProperties &MFProps = MF.getProperties();56 57#ifndef NDEBUG58  if (!MFProps.verifyRequiredProperties(RequiredProperties)) {59    errs() << "MachineFunctionProperties required by " << getPassName()60           << " pass are not met by function " << F.getName() << ".\n"61           << "Required properties: ";62    RequiredProperties.print(errs());63    errs() << "\nCurrent properties: ";64    MFProps.print(errs());65    errs() << "\n";66    llvm_unreachable("MachineFunctionProperties check failed");67  }68#endif69  // Collect the MI count of the function before the pass.70  unsigned CountBefore, CountAfter;71 72  // Check if the user asked for size remarks.73  bool ShouldEmitSizeRemarks =74      F.getParent()->shouldEmitInstrCountChangedRemark();75 76  // If we want size remarks, collect the number of MachineInstrs in our77  // MachineFunction before the pass runs.78  if (ShouldEmitSizeRemarks)79    CountBefore = MF.getInstructionCount();80 81  // For --print-changed, if the function name is a candidate, save the82  // serialized MF to be compared later.83  SmallString<0> BeforeStr, AfterStr;84  StringRef PassID;85  if (PrintChanged != ChangePrinter::None) {86    if (const PassInfo *PI = Pass::lookupPassInfo(getPassID()))87      PassID = PI->getPassArgument();88  }89  const bool IsInterestingPass = isPassInPrintList(PassID);90  const bool ShouldPrintChanged = PrintChanged != ChangePrinter::None &&91                                  IsInterestingPass &&92                                  isFunctionInPrintList(MF.getName());93  if (ShouldPrintChanged) {94    raw_svector_ostream OS(BeforeStr);95    MF.print(OS);96  }97 98  MFProps.reset(ClearedProperties);99 100  bool RV;101  if (DroppedVarStatsMIR) {102    DroppedVariableStatsMIR DroppedVarStatsMF;103    auto PassName = getPassName();104    DroppedVarStatsMF.runBeforePass(PassName, &MF);105    RV = runOnMachineFunction(MF);106    DroppedVarStatsMF.runAfterPass(PassName, &MF);107  } else {108    RV = runOnMachineFunction(MF);109  }110 111  if (ShouldEmitSizeRemarks) {112    // We wanted size remarks. Check if there was a change to the number of113    // MachineInstrs in the module. Emit a remark if there was a change.114    CountAfter = MF.getInstructionCount();115    if (CountBefore != CountAfter) {116      MachineOptimizationRemarkEmitter MORE(MF, nullptr);117      MORE.emit([&]() {118        int64_t Delta = static_cast<int64_t>(CountAfter) -119                        static_cast<int64_t>(CountBefore);120        MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",121                                            MF.getFunction().getSubprogram(),122                                            &MF.front());123        R << NV("Pass", getPassName())124          << ": Function: " << NV("Function", F.getName()) << ": "125          << "MI Instruction count changed from "126          << NV("MIInstrsBefore", CountBefore) << " to "127          << NV("MIInstrsAfter", CountAfter)128          << "; Delta: " << NV("Delta", Delta);129        return R;130      });131    }132  }133 134  MFProps.set(SetProperties);135 136  // For --print-changed, print if the serialized MF has changed. Modes other137  // than quiet/verbose are unimplemented and treated the same as 'quiet'.138  if (ShouldPrintChanged || !IsInterestingPass) {139    if (ShouldPrintChanged) {140      raw_svector_ostream OS(AfterStr);141      MF.print(OS);142    }143    if (IsInterestingPass && BeforeStr != AfterStr) {144      errs() << ("*** IR Dump After " + getPassName() + " (" + PassID +145                 ") on " + MF.getName() + " ***\n");146      switch (PrintChanged) {147      case ChangePrinter::None:148        llvm_unreachable("");149      case ChangePrinter::Quiet:150      case ChangePrinter::Verbose:151      case ChangePrinter::DotCfgQuiet:   // unimplemented152      case ChangePrinter::DotCfgVerbose: // unimplemented153        errs() << AfterStr;154        break;155      case ChangePrinter::DiffQuiet:156      case ChangePrinter::DiffVerbose:157      case ChangePrinter::ColourDiffQuiet:158      case ChangePrinter::ColourDiffVerbose: {159        bool Color = llvm::is_contained(160            {ChangePrinter::ColourDiffQuiet, ChangePrinter::ColourDiffVerbose},161            PrintChanged.getValue());162        StringRef Removed = Color ? "\033[31m-%l\033[0m\n" : "-%l\n";163        StringRef Added = Color ? "\033[32m+%l\033[0m\n" : "+%l\n";164        StringRef NoChange = " %l\n";165        errs() << doSystemDiff(BeforeStr, AfterStr, Removed, Added, NoChange);166        break;167      }168      }169    } else if (llvm::is_contained({ChangePrinter::Verbose,170                                   ChangePrinter::DiffVerbose,171                                   ChangePrinter::ColourDiffVerbose},172                                  PrintChanged.getValue())) {173      const char *Reason =174          IsInterestingPass ? " omitted because no change" : " filtered out";175      errs() << "*** IR Dump After " << getPassName();176      if (!PassID.empty())177        errs() << " (" << PassID << ")";178      errs() << " on " << MF.getName() + Reason + " ***\n";179    }180  }181  return RV;182}183 184void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {185  AU.addRequired<MachineModuleInfoWrapperPass>();186  AU.addPreserved<MachineModuleInfoWrapperPass>();187 188  // MachineFunctionPass preserves all LLVM IR passes, but there's no189  // high-level way to express this. Instead, just list a bunch of190  // passes explicitly. This does not include setPreservesCFG,191  // because CodeGen overloads that to mean preserving the MachineBasicBlock192  // CFG in addition to the LLVM IR CFG.193  AU.addPreserved<BasicAAWrapperPass>();194  AU.addPreserved<DominanceFrontierWrapperPass>();195  AU.addPreserved<DominatorTreeWrapperPass>();196  AU.addPreserved<AAResultsWrapperPass>();197  AU.addPreserved<GlobalsAAWrapperPass>();198  AU.addPreserved<IVUsersWrapperPass>();199  AU.addPreserved<LoopInfoWrapperPass>();200  AU.addPreserved<MemoryDependenceWrapperPass>();201  AU.addPreserved<ScalarEvolutionWrapperPass>();202  AU.addPreserved<SCEVAAWrapperPass>();203 204  FunctionPass::getAnalysisUsage(AU);205}206