LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMOptimizeBarriersPass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 35 35 100.0 %
Date: 2017-09-14 15:23:50 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARMOptimizeBarriersPass - two DMBs without a memory access in between,
       2             : //removed one -===//
       3             : //
       4             : //                     The LLVM Compiler Infrastructure
       5             : //
       6             : // This file is distributed under the University of Illinois Open Source
       7             : // License. See LICENSE.TXT for details.
       8             : //
       9             : //===------------------------------------------------------------------------------------------===//
      10             : 
      11             : #include "ARM.h"
      12             : #include "ARMInstrInfo.h"
      13             : #include "ARMMachineFunctionInfo.h"
      14             : #include "llvm/ADT/Statistic.h"
      15             : #include "llvm/CodeGen/MachineFunctionPass.h"
      16             : using namespace llvm;
      17             : 
      18             : #define DEBUG_TYPE "double barriers"
      19             : 
      20             : STATISTIC(NumDMBsRemoved, "Number of DMBs removed");
      21             : 
      22             : namespace {
      23        2295 : class ARMOptimizeBarriersPass : public MachineFunctionPass {
      24             : public:
      25             :   static char ID;
      26        2322 :   ARMOptimizeBarriersPass() : MachineFunctionPass(ID) {}
      27             : 
      28             :   bool runOnMachineFunction(MachineFunction &Fn) override;
      29             : 
      30        2316 :   MachineFunctionProperties getRequiredProperties() const override {
      31        6948 :     return MachineFunctionProperties().set(
      32        6948 :         MachineFunctionProperties::Property::NoVRegs);
      33             :   }
      34             : 
      35        2315 :   StringRef getPassName() const override { return "optimise barriers pass"; }
      36             : };
      37             : char ARMOptimizeBarriersPass::ID = 0;
      38             : }
      39             : 
      40             : // Returns whether the instruction can safely move past a DMB instruction
      41             : // The current implementation allows this iif MI does not have any possible
      42             : // memory access
      43      112880 : static bool CanMovePastDMB(const MachineInstr *MI) {
      44      259610 :   return !(MI->mayLoad() ||
      45      175693 :           MI->mayStore() ||
      46      139542 :           MI->hasUnmodeledSideEffects() ||
      47       58053 :           MI->isCall() ||
      48      165406 :           MI->isReturn());
      49             : }
      50             : 
      51       10850 : bool ARMOptimizeBarriersPass::runOnMachineFunction(MachineFunction &MF) {
      52       10850 :   if (skipFunction(*MF.getFunction()))
      53             :     return false;
      54             : 
      55             :   // Vector to store the DMBs we will remove after the first iteration
      56       10842 :   std::vector<MachineInstr *> ToRemove;
      57             :   // DMBType is the Imm value of the first operand. It determines whether it's a
      58             :   // DMB ish, dmb sy, dmb osh, etc
      59       10842 :   int64_t DMBType = -1;
      60             : 
      61             :   // Find a dmb. If we can move it until the next dmb, tag the second one for
      62             :   // removal
      63       47189 :   for (auto &MBB : MF) {
      64             :     // Will be true when we have seen a DMB, and not seen any instruction since
      65             :     // that cannot move past a DMB
      66       14663 :     bool IsRemovableNextDMB = false;
      67      284634 :     for (auto &MI : MBB) {
      68      112991 :       if (MI.getOpcode() == ARM::DMB) {
      69         111 :         if (IsRemovableNextDMB) {
      70             :           // If the Imm of this DMB is the same as that of the last DMB, we can
      71             :           // tag this second DMB for removal
      72           6 :           if (MI.getOperand(0).getImm() == DMBType) {
      73          10 :             ToRemove.push_back(&MI);
      74             :           } else {
      75             :             // If it has a different DMBType, we cannot remove it, but will scan
      76             :             // for the next DMB, recording this DMB's type as last seen DMB type
      77             :             DMBType = MI.getOperand(0).getImm();
      78             :           }
      79             :         } else {
      80             :           // After we see a DMB, a next one is removable
      81         105 :           IsRemovableNextDMB = true;
      82         105 :           DMBType = MI.getOperand(0).getImm();
      83             :         }
      84      112880 :       } else if (!CanMovePastDMB(&MI)) {
      85             :         // If we find an instruction unable to pass past a DMB, a next DMB is
      86             :         // not removable
      87       68623 :         IsRemovableNextDMB = false;
      88             :       }
      89             :     }
      90             :   }
      91       10842 :   bool Changed = false;
      92             :   // Remove the tagged DMB
      93       43373 :   for (auto MI : ToRemove) {
      94           5 :     MI->eraseFromParent();
      95           5 :     ++NumDMBsRemoved;
      96           5 :     Changed = true;
      97             :   }
      98             : 
      99       10842 :   return Changed;
     100             : }
     101             : 
     102             : /// createARMOptimizeBarriersPass - Returns an instance of the remove double
     103             : /// barriers
     104             : /// pass.
     105        2322 : FunctionPass *llvm::createARMOptimizeBarriersPass() {
     106        4644 :   return new ARMOptimizeBarriersPass();
     107             : }

Generated by: LCOV version 1.13