LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - Legalizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 69 69 100.0 %
Date: 2017-09-14 15:23:50 Functions: 7 7 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/SetVector.h"
      18             : #include "llvm/CodeGen/GlobalISel/LegalizerCombiner.h"
      19             : #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
      20             : #include "llvm/CodeGen/GlobalISel/Utils.h"
      21             : #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
      22             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      23             : #include "llvm/CodeGen/TargetPassConfig.h"
      24             : #include "llvm/Support/Debug.h"
      25             : #include "llvm/Target/TargetInstrInfo.h"
      26             : #include "llvm/Target/TargetSubtargetInfo.h"
      27             : 
      28             : #include <iterator>
      29             : 
      30             : #define DEBUG_TYPE "legalizer"
      31             : 
      32             : using namespace llvm;
      33             : 
      34             : char Legalizer::ID = 0;
      35       53279 : INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
      36             :                       "Legalize the Machine IR a function's Machine IR", false,
      37             :                       false)
      38       53279 : INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
      39      727249 : INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
      40             :                     "Legalize the Machine IR a function's Machine IR", false,
      41             :                     false)
      42             : 
      43         206 : Legalizer::Legalizer() : MachineFunctionPass(ID) {
      44         206 :   initializeLegalizerPass(*PassRegistry::getPassRegistry());
      45         206 : }
      46             : 
      47         185 : void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
      48         185 :   AU.addRequired<TargetPassConfig>();
      49         185 :   MachineFunctionPass::getAnalysisUsage(AU);
      50         185 : }
      51             : 
      52         986 : void Legalizer::init(MachineFunction &MF) {
      53         986 : }
      54             : 
      55        1058 : bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
      56             :   // If the ISel pipeline failed, do not bother running that pass.
      57        2116 :   if (MF.getProperties().hasProperty(
      58             :           MachineFunctionProperties::Property::FailedISel))
      59             :     return false;
      60             :   DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
      61         986 :   init(MF);
      62         986 :   const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
      63         986 :   MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
      64         986 :   LegalizerHelper Helper(MF);
      65             : 
      66             :   // FIXME: an instruction may need more than one pass before it is legal. For
      67             :   // example on most architectures <3 x i3> is doubly-illegal. It would
      68             :   // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We
      69             :   // probably want a worklist of instructions rather than naive iterate until
      70             :   // convergence for performance reasons.
      71         986 :   bool Changed = false;
      72         986 :   MachineBasicBlock::iterator NextMI;
      73        4028 :   for (auto &MBB : MF) {
      74       14620 :     for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
      75             :       // Get the next Instruction before we try to legalize, because there's a
      76             :       // good chance MI will be deleted.
      77        5717 :       NextMI = std::next(MI);
      78             : 
      79             :       // Only legalize pre-isel generic instructions: others don't have types
      80             :       // and are assumed to be legal.
      81       17151 :       if (!isPreISelGenericOpcode(MI->getOpcode()))
      82        3531 :         continue;
      83        2186 :       unsigned NumNewInsns = 0;
      84             :       using VecType = SetVector<MachineInstr *, SmallVector<MachineInstr *, 8>>;
      85        4360 :       VecType WorkList;
      86        4360 :       VecType CombineList;
      87        9089 :       Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) {
      88             :         // Only legalize pre-isel generic instructions.
      89             :         // Legalization process could generate Target specific pseudo
      90             :         // instructions with generic types. Don't record them
      91        7593 :         if (isPreISelGenericOpcode(MI->getOpcode())) {
      92        1461 :           ++NumNewInsns;
      93        1461 :           WorkList.insert(MI);
      94        1461 :           CombineList.insert(MI);
      95             :         }
      96        2531 :       });
      97        2186 :       WorkList.insert(&*MI);
      98        4372 :       LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo());
      99        2186 :       bool Changed = false;
     100             :       LegalizerHelper::LegalizeResult Res;
     101             :       do {
     102             :         assert(!WorkList.empty() && "Expecting illegal ops");
     103        9488 :         while (!WorkList.empty()) {
     104        3647 :           NumNewInsns = 0;
     105        3647 :           MachineInstr *CurrInst = WorkList.pop_back_val();
     106        3647 :           Res = Helper.legalizeInstrStep(*CurrInst);
     107             :           // Error out if we couldn't legalize this instruction. We may want to
     108             :           // fall back to DAG ISel instead in the future.
     109        3647 :           if (Res == LegalizerHelper::UnableToLegalize) {
     110          12 :             Helper.MIRBuilder.stopRecordingInsertions();
     111             :             if (Res == LegalizerHelper::UnableToLegalize) {
     112          24 :               reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
     113             :                                  "unable to legalize instruction", *CurrInst);
     114          12 :               return false;
     115             :             }
     116             :           }
     117        3635 :           Changed |= Res == LegalizerHelper::Legalized;
     118             :           // If CurrInst was legalized, there's a good chance that it might have
     119             :           // been erased. So remove it from the Combine List.
     120        3635 :           if (Res == LegalizerHelper::Legalized)
     121         458 :             CombineList.remove(CurrInst);
     122             : 
     123             : #ifndef NDEBUG
     124             :           if (NumNewInsns)
     125             :             for (unsigned I = WorkList.size() - NumNewInsns,
     126             :                           E = WorkList.size();
     127             :                  I != E; ++I)
     128             :               DEBUG(dbgs() << ".. .. New MI: " << *WorkList[I];);
     129             : #endif
     130             :         }
     131             :         // Do the combines.
     132        4932 :         while (!CombineList.empty()) {
     133        1363 :           NumNewInsns = 0;
     134        1363 :           MachineInstr *CurrInst = CombineList.pop_back_val();
     135        2726 :           SmallVector<MachineInstr *, 4> DeadInstructions;
     136        1363 :           Changed |= C.tryCombineInstruction(*CurrInst, DeadInstructions);
     137        4275 :           for (auto *DeadMI : DeadInstructions) {
     138             :             DEBUG(dbgs() << ".. Erasing Dead Instruction " << *DeadMI);
     139         186 :             CombineList.remove(DeadMI);
     140         186 :             WorkList.remove(DeadMI);
     141         186 :             DeadMI->eraseFromParent();
     142             :           }
     143             : #ifndef NDEBUG
     144             :           if (NumNewInsns)
     145             :             for (unsigned I = CombineList.size() - NumNewInsns,
     146             :                           E = CombineList.size();
     147             :                  I != E; ++I)
     148             :               DEBUG(dbgs() << ".. .. Combine New MI: " << *CombineList[I];);
     149             : #endif
     150             :         }
     151        2206 :       } while (!WorkList.empty());
     152             : 
     153        2174 :       Helper.MIRBuilder.stopRecordingInsertions();
     154             :     }
     155             :   }
     156             : 
     157         974 :   MachineRegisterInfo &MRI = MF.getRegInfo();
     158        1948 :   MachineIRBuilder MIRBuilder(MF);
     159         974 :   LegalizerCombiner C(MIRBuilder, MRI);
     160        3976 :   for (auto &MBB : MF) {
     161       25227 :     for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
     162             :       // Get the next Instruction before we try to legalize, because there's a
     163             :       // good chance MI will be deleted.
     164             :       // TOOD: Perhaps move this to a combiner pass later?.
     165        7355 :       NextMI = std::next(MI);
     166       14710 :       SmallVector<MachineInstr *, 4> DeadInsts;
     167        7355 :       Changed |= C.tryCombineMerges(*MI, DeadInsts);
     168       22103 :       for (auto *DeadMI : DeadInsts)
     169          38 :         DeadMI->eraseFromParent();
     170             :     }
     171             :   }
     172             : 
     173             :   return Changed;
     174             : }

Generated by: LCOV version 1.13