LLVM  14.0.0git
ARCBranchFinalize.cpp
Go to the documentation of this file.
1 //===- ARCBranchFinalize.cpp - ARC conditional branches ---------*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass takes existing conditional branches and expands them into longer
10 // range conditional branches.
11 //===----------------------------------------------------------------------===//
12 
13 #include "ARCInstrInfo.h"
14 #include "ARCTargetMachine.h"
15 #include "MCTargetDesc/ARCInfo.h"
19 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/Support/Debug.h"
23 #include <vector>
24 
25 #define DEBUG_TYPE "arc-branch-finalize"
26 
27 using namespace llvm;
28 
29 namespace llvm {
30 
33 
34 } // end namespace llvm
35 
36 namespace {
37 
38 class ARCBranchFinalize : public MachineFunctionPass {
39 public:
40  static char ID;
41 
42  ARCBranchFinalize() : MachineFunctionPass(ID) {
44  }
45 
46  StringRef getPassName() const override {
47  return "ARC Branch Finalization Pass";
48  }
49 
50  bool runOnMachineFunction(MachineFunction &MF) override;
51  void replaceWithBRcc(MachineInstr *MI) const;
52  void replaceWithCmpBcc(MachineInstr *MI) const;
53 
54 private:
55  const ARCInstrInfo *TII{nullptr};
56 };
57 
58 char ARCBranchFinalize::ID = 0;
59 
60 } // end anonymous namespace
61 
62 INITIALIZE_PASS_BEGIN(ARCBranchFinalize, "arc-branch-finalize",
63  "ARC finalize branches", false, false)
65 INITIALIZE_PASS_END(ARCBranchFinalize, "arc-branch-finalize",
67 
68 // BRcc has 6 supported condition codes, which differ from the 16
69 // condition codes supported in the predicated instructions:
70 // EQ -- 000
71 // NE -- 001
72 // LT -- 010
73 // GE -- 011
74 // LO -- 100
75 // HS -- 101
76 static unsigned getCCForBRcc(unsigned CC) {
77  switch (CC) {
78  case ARCCC::EQ:
79  return 0;
80  case ARCCC::NE:
81  return 1;
82  case ARCCC::LT:
83  return 2;
84  case ARCCC::GE:
85  return 3;
86  case ARCCC::LO:
87  return 4;
88  case ARCCC::HS:
89  return 5;
90  default:
91  return -1U;
92  }
93 }
94 
95 static bool isBRccPseudo(MachineInstr *MI) {
96  return !(MI->getOpcode() != ARC::BRcc_rr_p &&
97  MI->getOpcode() != ARC::BRcc_ru6_p);
98 }
99 
100 static unsigned getBRccForPseudo(MachineInstr *MI) {
101  assert(isBRccPseudo(MI) && "Can't get BRcc for wrong instruction.");
102  if (MI->getOpcode() == ARC::BRcc_rr_p)
103  return ARC::BRcc_rr;
104  return ARC::BRcc_ru6;
105 }
106 
107 static unsigned getCmpForPseudo(MachineInstr *MI) {
108  assert(isBRccPseudo(MI) && "Can't get BRcc for wrong instruction.");
109  if (MI->getOpcode() == ARC::BRcc_rr_p)
110  return ARC::CMP_rr;
111  return ARC::CMP_ru6;
112 }
113 
114 void ARCBranchFinalize::replaceWithBRcc(MachineInstr *MI) const {
115  LLVM_DEBUG(dbgs() << "Replacing pseudo branch with BRcc\n");
116  unsigned CC = getCCForBRcc(MI->getOperand(3).getImm());
117  if (CC != -1U) {
118  BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
119  TII->get(getBRccForPseudo(MI)))
120  .addMBB(MI->getOperand(0).getMBB())
121  .addReg(MI->getOperand(1).getReg())
122  .add(MI->getOperand(2))
123  .addImm(getCCForBRcc(MI->getOperand(3).getImm()));
124  MI->eraseFromParent();
125  } else {
126  replaceWithCmpBcc(MI);
127  }
128 }
129 
130 void ARCBranchFinalize::replaceWithCmpBcc(MachineInstr *MI) const {
131  LLVM_DEBUG(dbgs() << "Branch: " << *MI << "\n");
132  LLVM_DEBUG(dbgs() << "Replacing pseudo branch with Cmp + Bcc\n");
133  BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
134  TII->get(getCmpForPseudo(MI)))
135  .addReg(MI->getOperand(1).getReg())
136  .add(MI->getOperand(2));
137  BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(ARC::Bcc))
138  .addMBB(MI->getOperand(0).getMBB())
139  .addImm(MI->getOperand(3).getImm());
140  MI->eraseFromParent();
141 }
142 
143 bool ARCBranchFinalize::runOnMachineFunction(MachineFunction &MF) {
144  LLVM_DEBUG(dbgs() << "Running ARC Branch Finalize on " << MF.getName()
145  << "\n");
146  std::vector<MachineInstr *> Branches;
147  bool Changed = false;
148  unsigned MaxSize = 0;
149  TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
150  std::map<MachineBasicBlock *, unsigned> BlockToPCMap;
151  std::vector<std::pair<MachineInstr *, unsigned>> BranchToPCList;
152  unsigned PC = 0;
153 
154  for (auto &MBB : MF) {
155  BlockToPCMap.insert(std::make_pair(&MBB, PC));
156  for (auto &MI : MBB) {
157  unsigned Size = TII->getInstSizeInBytes(MI);
158  if (Size > 8 || Size == 0) {
159  LLVM_DEBUG(dbgs() << "Unknown (or size 0) size for: " << MI << "\n");
160  } else {
161  MaxSize += Size;
162  }
163  if (MI.isBranch()) {
164  Branches.push_back(&MI);
165  BranchToPCList.emplace_back(&MI, PC);
166  }
167  PC += Size;
168  }
169  }
170  for (auto P : BranchToPCList) {
171  if (isBRccPseudo(P.first))
172  isInt<9>(MaxSize) ? replaceWithBRcc(P.first) : replaceWithCmpBcc(P.first);
173  }
174 
175  LLVM_DEBUG(dbgs() << "Estimated function size for " << MF.getName() << ": "
176  << MaxSize << "\n");
177 
178  return Changed;
179 }
180 
182  return new ARCBranchFinalize();
183 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
arc
objc arc
Definition: ObjCARCOpts.cpp:610
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::ARCCC::NE
@ NE
Definition: ARCInfo.h:27
TargetInstrInfo.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
MachineRegisterInfo.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::ARCSubtarget
Definition: ARCSubtarget.h:31
finalize
arc branch finalize
Definition: ARCBranchFinalize.cpp:65
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(ARCBranchFinalize, "arc-branch-finalize", "ARC finalize branches", false, false) INITIALIZE_PASS_END(ARCBranchFinalize
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
ARCInfo.h
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
Passes.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:622
llvm::ARCCC::EQ
@ EQ
Definition: ARCInfo.h:26
getCmpForPseudo
static unsigned getCmpForPseudo(MachineInstr *MI)
Definition: ARCBranchFinalize.cpp:107
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::ARCCC::LO
@ LO
Definition: ARCInfo.h:30
getCCForBRcc
arc branch ARC finalize static false unsigned getCCForBRcc(unsigned CC)
Definition: ARCBranchFinalize.cpp:76
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::initializeARCBranchFinalizePass
void initializeARCBranchFinalizePass(PassRegistry &Registry)
MachineFunctionPass.h
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:541
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ARCCC::GE
@ GE
Definition: ARCInfo.h:35
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
ARCTargetMachine.h
ARCInstrInfo.h
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::ARCInstrInfo
Definition: ARCInstrInfo.h:26
getBRccForPseudo
static unsigned getBRccForPseudo(MachineInstr *MI)
Definition: ARCBranchFinalize.cpp:100
llvm::Registry
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:44
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::ARCCC::LT
@ LT
Definition: ARCInfo.h:36
llvm::createARCBranchFinalizePass
FunctionPass * createARCBranchFinalizePass()
Definition: ARCBranchFinalize.cpp:181
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
branches
arc branch ARC finalize branches
Definition: ARCBranchFinalize.cpp:66
InitializePasses.h
Debug.h
isBRccPseudo
static bool isBRccPseudo(MachineInstr *MI)
Definition: ARCBranchFinalize.cpp:95
llvm::ARCCC::HS
@ HS
Definition: ARCInfo.h:31
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38