LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - Legalizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 53 57 93.0 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- llvm/CodeGen/GlobalISel/Legalizer.cpp -----------------------------===//
       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             : /// \file This file implements the LegalizerHelper class to legalize individual
      11             : /// instructions and the LegalizePass wrapper pass for the primary
      12             : /// legalization.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "llvm/CodeGen/GlobalISel/Legalizer.h"
      17             : #include "llvm/ADT/PostOrderIterator.h"
      18             : #include "llvm/ADT/SetVector.h"
      19             : #include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
      20             : #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
      21             : #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
      22             : #include "llvm/CodeGen/GlobalISel/Utils.h"
      23             : #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
      24             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      25             : #include "llvm/CodeGen/TargetPassConfig.h"
      26             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      27             : #include "llvm/Support/Debug.h"
      28             : 
      29             : #include <iterator>
      30             : 
      31             : #define DEBUG_TYPE "legalizer"
      32             : 
      33             : using namespace llvm;
      34             : 
      35             : char Legalizer::ID = 0;
      36       85394 : INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
      37             :                       "Legalize the Machine IR a function's Machine IR", false,
      38             :                       false)
      39       85394 : INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
      40      655633 : INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
      41             :                     "Legalize the Machine IR a function's Machine IR", false,
      42             :                     false)
      43             : 
      44         355 : Legalizer::Legalizer() : MachineFunctionPass(ID) {
      45         355 :   initializeLegalizerPass(*PassRegistry::getPassRegistry());
      46         355 : }
      47             : 
      48         311 : void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
      49             :   AU.addRequired<TargetPassConfig>();
      50         311 :   getSelectionDAGFallbackAnalysisUsage(AU);
      51         311 :   MachineFunctionPass::getAnalysisUsage(AU);
      52         311 : }
      53             : 
      54        1512 : void Legalizer::init(MachineFunction &MF) {
      55        1512 : }
      56             : 
      57             : static bool isArtifact(const MachineInstr &MI) {
      58             :   switch (MI.getOpcode()) {
      59             :   default:
      60             :     return false;
      61             :   case TargetOpcode::G_TRUNC:
      62             :   case TargetOpcode::G_ZEXT:
      63             :   case TargetOpcode::G_ANYEXT:
      64             :   case TargetOpcode::G_SEXT:
      65             :   case TargetOpcode::G_MERGE_VALUES:
      66             :   case TargetOpcode::G_UNMERGE_VALUES:
      67             :     return true;
      68             :   }
      69             : }
      70             : 
      71        1600 : bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
      72             :   // If the ISel pipeline failed, do not bother running that pass.
      73        1600 :   if (MF.getProperties().hasProperty(
      74             :           MachineFunctionProperties::Property::FailedISel))
      75             :     return false;
      76             :   LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
      77        1512 :   init(MF);
      78        1512 :   const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
      79             :   MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
      80        1512 :   LegalizerHelper Helper(MF);
      81             : 
      82             :   const size_t NumBlocks = MF.size();
      83        1512 :   MachineRegisterInfo &MRI = MF.getRegInfo();
      84             : 
      85             :   // Populate Insts
      86        1511 :   GISelWorkList<256> InstList;
      87        1511 :   GISelWorkList<128> ArtifactList;
      88             :   ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
      89             :   // Perform legalization bottom up so we can DCE as we legalize.
      90             :   // Traverse BB in RPOT and within each basic block, add insts top down,
      91             :   // so when we pop_back_val in the legalization process, we traverse bottom-up.
      92        3140 :   for (auto *MBB : RPOT) {
      93        1628 :     if (MBB->empty())
      94             :       continue;
      95       12083 :     for (MachineInstr &MI : *MBB) {
      96             :       // Only legalize pre-isel generic instructions: others don't have types
      97             :       // and are assumed to be legal.
      98       20950 :       if (!isPreISelGenericOpcode(MI.getOpcode()))
      99             :         continue;
     100             :       if (isArtifact(MI))
     101        1538 :         ArtifactList.insert(&MI);
     102             :       else
     103        3422 :         InstList.insert(&MI);
     104             :     }
     105             :   }
     106        1512 :   Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) {
     107             :     // Only legalize pre-isel generic instructions.
     108             :     // Legalization process could generate Target specific pseudo
     109             :     // instructions with generic types. Don't record them
     110             :     if (isPreISelGenericOpcode(MI->getOpcode())) {
     111             :       if (isArtifact(*MI))
     112             :         ArtifactList.insert(MI);
     113             :       else
     114             :         InstList.insert(MI);
     115             :     }
     116             :     LLVM_DEBUG(dbgs() << ".. .. New MI: " << *MI;);
     117             :   });
     118        1512 :   const LegalizerInfo &LInfo(Helper.getLegalizerInfo());
     119        1512 :   LegalizationArtifactCombiner ArtCombiner(Helper.MIRBuilder, MF.getRegInfo(), LInfo);
     120             :   auto RemoveDeadInstFromLists = [&InstList,
     121             :                                   &ArtifactList](MachineInstr *DeadMI) {
     122          51 :     InstList.remove(DeadMI);
     123        1840 :     ArtifactList.remove(DeadMI);
     124             :   };
     125             :   bool Changed = false;
     126             :   do {
     127        8104 :     while (!InstList.empty()) {
     128        5946 :       MachineInstr &MI = *InstList.pop_back_val();
     129             :       assert(isPreISelGenericOpcode(MI.getOpcode()) && "Expecting generic opcode");
     130        5946 :       if (isTriviallyDead(MI, MRI)) {
     131             :         LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
     132          69 :         MI.eraseFromParentAndMarkDBGValuesForRemoval();
     133          69 :         continue;
     134             :       }
     135             : 
     136             :       // Do the legalization for this instruction.
     137        5877 :       auto Res = Helper.legalizeInstrStep(MI);
     138             :       // Error out if we couldn't legalize this instruction. We may want to
     139             :       // fall back to DAG ISel instead in the future.
     140        5877 :       if (Res == LegalizerHelper::UnableToLegalize) {
     141          30 :         Helper.MIRBuilder.stopRecordingInsertions();
     142          30 :         reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
     143             :                            "unable to legalize instruction", MI);
     144          29 :         return false;
     145             :       }
     146        5847 :       Changed |= Res == LegalizerHelper::Legalized;
     147             :     }
     148        4149 :     while (!ArtifactList.empty()) {
     149        1991 :       MachineInstr &MI = *ArtifactList.pop_back_val();
     150             :       assert(isPreISelGenericOpcode(MI.getOpcode()) && "Expecting generic opcode");
     151        1991 :       if (isTriviallyDead(MI, MRI)) {
     152             :         LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
     153             :         RemoveDeadInstFromLists(&MI);
     154          51 :         MI.eraseFromParentAndMarkDBGValuesForRemoval();
     155         966 :         continue;
     156             :       }
     157             :       SmallVector<MachineInstr *, 4> DeadInstructions;
     158        1940 :       if (ArtCombiner.tryCombineInstruction(MI, DeadInstructions)) {
     159        2704 :         for (auto *DeadMI : DeadInstructions) {
     160             :           LLVM_DEBUG(dbgs() << ".. Erasing Dead Instruction " << *DeadMI);
     161             :           RemoveDeadInstFromLists(DeadMI);
     162        1789 :           DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
     163             :         }
     164             :         Changed = true;
     165             :         continue;
     166             :       }
     167             :       // If this was not an artifact (that could be combined away), this might
     168             :       // need special handling. Add it to InstList, so when it's processed
     169             :       // there, it has to be legal or specially handled.
     170             :       else
     171        1025 :         InstList.insert(&MI);
     172             :     }
     173        2158 :   } while (!InstList.empty());
     174             : 
     175             :   // For now don't support if new blocks are inserted - we would need to fix the
     176             :   // outerloop for that.
     177        1482 :   if (MF.size() != NumBlocks) {
     178             :     MachineOptimizationRemarkMissed R("gisel-legalize", "GISelFailure",
     179           0 :                                       MF.getFunction().getSubprogram(),
     180           0 :                                       /*MBB=*/nullptr);
     181           0 :     R << "inserting blocks is not supported yet";
     182           0 :     reportGISelFailure(MF, TPC, MORE, R);
     183             :     return false;
     184             :   }
     185             : 
     186             :   return Changed;
     187             : }

Generated by: LCOV version 1.13