1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===--- HexagonEarlyIfConv.cpp -------------------------------------------===// 2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This implements a Hexagon-specific if-conversion pass that runs on the 11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// SSA form. 12f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// In SSA it is not straightforward to represent instructions that condi- 13f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// tionally define registers, since a conditionally-defined register may 14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// only be used under the same condition on which the definition was based. 15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// To avoid complications of this nature, this patch will only generate 16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// predicated stores, and speculate other instructions from the "if-conver- 17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// ted" block. 18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The code will recognize CFG patterns where a block with a conditional 19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// branch "splits" into a "true block" and a "false block". Either of these 20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// could be omitted (in case of a triangle, for example). 21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If after conversion of the side block(s) the CFG allows it, the resul- 22f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// ting blocks may be merged. If the "join" block contained PHI nodes, they 23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// will be replaced with MUX (or MUX-like) instructions to maintain the 24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// semantics of the PHI. 25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Example: 27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg40<def> = L2_loadrub_io %vreg39<kill>, 1 29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg41<def> = S2_tstbit_i %vreg40<kill>, 0 30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jumpt %vreg41<kill>, <BB#5>, %PC<imp-def,dead> 31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jump <BB#4>, %PC<imp-def,dead> 32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Successors according to CFG: BB#4(62) BB#5(62) 33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// BB#4: derived from LLVM BB %if.then 35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Predecessors according to CFG: BB#3 36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg11<def> = A2_addp %vreg6, %vreg10 37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// S2_storerd_io %vreg32, 16, %vreg11 38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Successors according to CFG: BB#5 39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// BB#5: derived from LLVM BB %if.end 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Predecessors according to CFG: BB#3 BB#4 42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg12<def> = PHI %vreg6, <BB#3>, %vreg11, <BB#4> 43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg13<def> = A2_addp %vreg7, %vreg12 44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg42<def> = C2_cmpeqi %vreg9, 10 45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jumpf %vreg42<kill>, <BB#3>, %PC<imp-def,dead> 46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jump <BB#6>, %PC<imp-def,dead> 47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Successors according to CFG: BB#6(4) BB#3(124) 48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// would become: 50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg40<def> = L2_loadrub_io %vreg39<kill>, 1 52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg41<def> = S2_tstbit_i %vreg40<kill>, 0 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// spec-> %vreg11<def> = A2_addp %vreg6, %vreg10 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// pred-> S2_pstorerdf_io %vreg41, %vreg32, 16, %vreg11 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg46<def> = MUX64_rr %vreg41, %vreg6, %vreg11 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg13<def> = A2_addp %vreg7, %vreg46 57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// %vreg42<def> = C2_cmpeqi %vreg9, 10 58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jumpf %vreg42<kill>, <BB#3>, %PC<imp-def,dead> 59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// J2_jump <BB#6>, %PC<imp-def,dead> 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Successors according to CFG: BB#6 BB#3 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#define DEBUG_TYPE "hexagon-eif" 63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/DenseSet.h" 65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/SetVector.h" 66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineDominators.h" 68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineFunctionPass.h" 69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h" 70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineLoopInfo.h" 71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineRegisterInfo.h" 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/Passes.h" 73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/CommandLine.h" 74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/Debug.h" 75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Target/TargetInstrInfo.h" 77f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Target/TargetMachine.h" 78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "HexagonTargetMachine.h" 79f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 80f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include <functional> 81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm; 83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace llvm { 85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionPass *createHexagonEarlyIfConversion(); 86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void initializeHexagonEarlyIfConversionPass(PassRegistry& Registry); 87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace { 90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::opt<bool> EnableHexagonBP("enable-hexagon-br-prob", cl::Hidden, 91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::init(false), cl::desc("Enable branch probability info")); 92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::opt<unsigned> SizeLimit("eif-limit", cl::init(6), cl::Hidden, 93f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Size limit in Hexagon early if-conversion")); 94f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar struct PrintMB { 96f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PrintMB(const MachineBasicBlock *B) : MB(B) {} 97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineBasicBlock *MB; 98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar raw_ostream &operator<< (raw_ostream &OS, const PrintMB &P) { 100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!P.MB) 101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return OS << "<none>"; 102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return OS << '#' << P.MB->getNumber(); 103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar struct FlowPattern { 106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FlowPattern() : SplitB(0), TrueB(0), FalseB(0), JoinB(0), PredR(0) {} 107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FlowPattern(MachineBasicBlock *B, unsigned PR, MachineBasicBlock *TB, 108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *FB, MachineBasicBlock *JB) 109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : SplitB(B), TrueB(TB), FalseB(FB), JoinB(JB), PredR(PR) {} 110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SplitB; 112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TrueB, *FalseB, *JoinB; 113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredR; 114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar struct PrintFP { 116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PrintFP(const FlowPattern &P, const TargetRegisterInfo &T) 117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : FP(P), TRI(T) {} 118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const FlowPattern &FP; 119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetRegisterInfo &TRI; 120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar friend raw_ostream &operator<< (raw_ostream &OS, const PrintFP &P); 121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar raw_ostream &operator<<(raw_ostream &OS, 123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const PrintFP &P) LLVM_ATTRIBUTE_UNUSED; 124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar raw_ostream &operator<<(raw_ostream &OS, const PrintFP &P) { 125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "{ SplitB:" << PrintMB(P.FP.SplitB) 126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << ", PredR:" << PrintReg(P.FP.PredR, &P.TRI) 127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << ", TrueB:" << PrintMB(P.FP.TrueB) << ", FalseB:" 128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << PrintMB(P.FP.FalseB) 129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << ", JoinB:" << PrintMB(P.FP.JoinB) << " }"; 130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return OS; 131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar class HexagonEarlyIfConversion : public MachineFunctionPass { 134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar public: 135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static char ID; 136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HexagonEarlyIfConversion() : MachineFunctionPass(ID), 137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TII(0), TRI(0), MFN(0), MRI(0), MDT(0), MLI(0) { 138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar initializeHexagonEarlyIfConversionPass(*PassRegistry::getPassRegistry()); 139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const char *getPassName() const override { 141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return "Hexagon early if conversion"; 142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void getAnalysisUsage(AnalysisUsage &AU) const override { 144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addRequired<MachineBranchProbabilityInfo>(); 145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addRequired<MachineDominatorTree>(); 146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addPreserved<MachineDominatorTree>(); 147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addRequired<MachineLoopInfo>(); 148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineFunctionPass::getAnalysisUsage(AU); 149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool runOnMachineFunction(MachineFunction &MF) override; 151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar private: 153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef DenseSet<MachineBasicBlock*> BlockSetType; 154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isPreheader(const MachineBasicBlock *B) const; 156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool matchFlowPattern(MachineBasicBlock *B, MachineLoop *L, 157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FlowPattern &FP); 158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool visitBlock(MachineBasicBlock *B, MachineLoop *L); 159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool visitLoop(MachineLoop *L); 160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool hasEHLabel(const MachineBasicBlock *B) const; 162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool hasUncondBranch(const MachineBasicBlock *B) const; 163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isValidCandidate(const MachineBasicBlock *B) const; 164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool usesUndefVReg(const MachineInstr *MI) const; 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isValid(const FlowPattern &FP) const; 166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned countPredicateDefs(const MachineBasicBlock *B) const; 167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned computePhiCost(MachineBasicBlock *B) const; 168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isProfitable(const FlowPattern &FP) const; 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isPredicableStore(const MachineInstr *MI) const; 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isSafeToSpeculate(const MachineInstr *MI) const; 171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned getCondStoreOpcode(unsigned Opc, bool IfTrue) const; 173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void predicateInstr(MachineBasicBlock *ToB, MachineBasicBlock::iterator At, 174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr *MI, unsigned PredR, bool IfTrue); 175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void predicateBlockNB(MachineBasicBlock *ToB, 176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator At, MachineBasicBlock *FromB, 177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredR, bool IfTrue); 178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void updatePhiNodes(MachineBasicBlock *WhereB, const FlowPattern &FP); 180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void convert(const FlowPattern &FP); 181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void removeBlock(MachineBasicBlock *B); 183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void eliminatePhis(MachineBasicBlock *B); 184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void replacePhiEdges(MachineBasicBlock *OldB, MachineBasicBlock *NewB); 185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void mergeBlocks(MachineBasicBlock *PredB, MachineBasicBlock *SuccB); 186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void simplifyFlowGraph(const FlowPattern &FP); 187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetInstrInfo *TII; 189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetRegisterInfo *TRI; 190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineFunction *MFN; 191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineRegisterInfo *MRI; 192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineDominatorTree *MDT; 193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineLoopInfo *MLI; 194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BlockSetType Deleted; 195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineBranchProbabilityInfo *MBPI; 196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar char HexagonEarlyIfConversion::ID = 0; 199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS(HexagonEarlyIfConversion, "hexagon-eif", 202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "Hexagon early if conversion", false, false) 203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isPreheader(const MachineBasicBlock *B) const { 205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B->succ_size() != 1) 206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = *B->succ_begin(); 208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineLoop *L = MLI->getLoopFor(SB); 209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return L && SB == L->getHeader(); 210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, 214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineLoop *L, FlowPattern &FP) { 215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Checking flow pattern at BB#" << B->getNumber() << "\n"); 216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Interested only in conditional branches, no .new, no new-value, etc. 218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Check the terminators directly, it's easier than handling all responses 219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // from AnalyzeBranch. 220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TB = 0, *FB = 0; 221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::const_iterator T1I = B->getFirstTerminator(); 222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (T1I == B->end()) 223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Opc = T1I->getOpcode(); 225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Opc != Hexagon::J2_jumpt && Opc != Hexagon::J2_jumpf) 226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredR = T1I->getOperand(0).getReg(); 228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Get the layout successor, or 0 if B does not have one. 230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineFunction::iterator NextBI = std::next(MachineFunction::iterator(B)); 231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *NextB = (NextBI != MFN->end()) ? &*NextBI : 0; 232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *T1B = T1I->getOperand(1).getMBB(); 234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::const_iterator T2I = std::next(T1I); 235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // The second terminator should be an unconditional branch. 236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(T2I == B->end() || T2I->getOpcode() == Hexagon::J2_jump); 237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *T2B = (T2I == B->end()) ? NextB 238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : T2I->getOperand(0).getMBB(); 239f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (T1B == T2B) { 240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // XXX merge if T1B == NextB, or convert branch to unconditional. 241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // mark as diamond with both sides equal? 242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Loop could be null for both. 245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MLI->getLoopFor(T1B) != L || MLI->getLoopFor(T2B) != L) 246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Record the true/false blocks in such a way that "true" means "if (PredR)", 249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // and "false" means "if (!PredR)". 250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Opc == Hexagon::J2_jumpt) 251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TB = T1B, FB = T2B; 252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TB = T2B, FB = T1B; 254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MDT->properlyDominates(B, TB) || !MDT->properlyDominates(B, FB)) 256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Detect triangle first. In case of a triangle, one of the blocks TB/FB 259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // can fall through into the other, in other words, it will be executed 260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // in both cases. We only want to predicate the block that is executed 261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // conditionally. 262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TNP = TB->pred_size(), FNP = FB->pred_size(); 263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TNS = TB->succ_size(), FNS = FB->succ_size(); 264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // A block is predicable if it has one predecessor (it must be B), and 266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // it has a single successor. In fact, the block has to end either with 267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // an unconditional branch (which can be predicated), or with a fall- 268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // through. 269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool TOk = (TNP == 1) && (TNS == 1); 270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool FOk = (FNP == 1) && (FNS == 1); 271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If neither is predicable, there is nothing interesting. 273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TOk && !FOk) 274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TSB = (TNS > 0) ? *TB->succ_begin() : 0; 277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *FSB = (FNS > 0) ? *FB->succ_begin() : 0; 278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *JB = 0; 279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TOk) { 281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FOk) { 282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB == FSB) 283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar JB = TSB; 284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Diamond: "if (P) then TB; else FB;". 285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // TOk && !FOk 287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB == FB) { 288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar JB = FB; 289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FB = 0; 290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // !TOk && FOk (at least one must be true by now). 294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FSB == TB) { 295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar JB = TB; 296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TB = 0; 297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Don't try to predicate loop preheaders. 300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if ((TB && isPreheader(TB)) || (FB && isPreheader(FB))) { 301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "One of blocks " << PrintMB(TB) << ", " << PrintMB(FB) 302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << " is a loop preheader. Skipping.\n"); 303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP = FlowPattern(B, PredR, TB, FB, JB); 307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Detected " << PrintFP(FP, *TRI) << "\n"); 308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// KLUDGE: HexagonInstrInfo::AnalyzeBranch won't work on a block that 313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// contains EH_LABEL. 314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::hasEHLabel(const MachineBasicBlock *B) const { 315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &I : *B) 316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I.isEHLabel()) 317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// KLUDGE: HexagonInstrInfo::AnalyzeBranch may be unable to recognize 323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// that a block can never fall-through. 324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::hasUncondBranch(const MachineBasicBlock *B) 325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const { 326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end(); 327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar while (I != E) { 328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I->isBarrier()) 329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ++I; 331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B) 337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const { 338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!B) 339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B->isEHPad() || B->hasAddressTaken()) 341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B->succ_size() == 0) 343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &MI : *B) { 346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MI.isDebugValue()) 347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MI.isConditionalBranch()) 349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Opc = MI.getOpcode(); 351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IsJMP = (Opc == Hexagon::J2_jump); 352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!isPredicableStore(&MI) && !IsJMP && !isSafeToSpeculate(&MI)) 353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Look for predicate registers defined by this instruction. It's ok 355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to speculate such an instruction, but the predicate register cannot 356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // be used outside of this block (or else it won't be possible to 357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // update the use of it after predication). PHI uses will be updated 358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to use a result of a MUX, and a MUX cannot be created for predicate 359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // registers. 360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (ConstMIOperands MO(MI); MO.isValid(); ++MO) { 361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MO->isReg() || !MO->isDef()) 362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned R = MO->getReg(); 364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TargetRegisterInfo::isVirtualRegister(R)) 365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MRI->getRegClass(R) != &Hexagon::PredRegsRegClass) 367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto U = MRI->use_begin(R); U != MRI->use_end(); ++U) 369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (U->getParent()->isPHI()) 370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::usesUndefVReg(const MachineInstr *MI) const { 378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (ConstMIOperands MO(*MI); MO.isValid(); ++MO) { 379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MO->isReg() || !MO->isUse()) 380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned R = MO->getReg(); 382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TargetRegisterInfo::isVirtualRegister(R)) 383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineInstr *DefI = MRI->getVRegDef(R); 385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // "Undefined" virtual registers are actually defined via IMPLICIT_DEF. 386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(DefI && "Expecting a reaching def in MRI"); 387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DefI->isImplicitDef()) 388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const { 395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (hasEHLabel(FP.SplitB)) // KLUDGE: see function definition 396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB && !isValidCandidate(FP.TrueB)) 398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.FalseB && !isValidCandidate(FP.FalseB)) 400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Check the PHIs in the join block. If any of them use a register 402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // that is defined as IMPLICIT_DEF, do not convert this. This can 403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // legitimately happen if one side of the split never executes, but 404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // the compiler is unable to prove it. That side may then seem to 405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // provide an "undef" value to the join block, however it will never 406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // execute at run-time. If we convert this case, the "undef" will 407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // be used in a MUX instruction, and that may seem like actually 408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // using an undefined value to other optimizations. This could lead 409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to trouble further down the optimization stream, cause assertions 410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to fail, etc. 411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.JoinB) { 412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineBasicBlock &B = *FP.JoinB; 413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &MI : B) { 414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MI.isPHI()) 415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (usesUndefVReg(&MI)) 417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DefR = MI.getOperand(0).getReg(); 419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetRegisterClass *RC = MRI->getRegClass(DefR); 420f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (RC == &Hexagon::PredRegsRegClass) 421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const { 429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(B->pred_size() <= 2); 430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B->pred_size() < 2) 431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return 0; 432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Cost = 0; 434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::const_iterator I, E = B->getFirstNonPHI(); 435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (I = B->begin(); I != E; ++I) { 436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineOperand &RO1 = I->getOperand(1); 437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineOperand &RO3 = I->getOperand(3); 438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(RO1.isReg() && RO3.isReg()); 439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Must have a MUX if the phi uses a subregister. 440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (RO1.getSubReg() != 0 || RO3.getSubReg() != 0) { 441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Cost++; 442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr *Def1 = MRI->getVRegDef(RO1.getReg()); 445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr *Def3 = MRI->getVRegDef(RO3.getReg()); 446de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!TII->isPredicable(*Def1) || !TII->isPredicable(*Def3)) 447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Cost++; 448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Cost; 450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned HexagonEarlyIfConversion::countPredicateDefs( 454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineBasicBlock *B) const { 455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredDefs = 0; 456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &MI : *B) { 457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (ConstMIOperands MO(MI); MO.isValid(); ++MO) { 458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MO->isReg() || !MO->isDef()) 459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned R = MO->getReg(); 461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TargetRegisterInfo::isVirtualRegister(R)) 462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MRI->getRegClass(R) == &Hexagon::PredRegsRegClass) 464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredDefs++; 465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return PredDefs; 468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isProfitable(const FlowPattern &FP) const { 472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB && FP.FalseB) { 473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Do not IfCovert if the branch is one sided. 475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MBPI) { 476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BranchProbability Prob(9, 10); 477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MBPI->getEdgeProbability(FP.SplitB, FP.TrueB) > Prob) 478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MBPI->getEdgeProbability(FP.SplitB, FP.FalseB) > Prob) 480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If both sides are predicable, convert them if they join, and the 484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // join block has no other predecessors. 485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TSB = *FP.TrueB->succ_begin(); 486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *FSB = *FP.FalseB->succ_begin(); 487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB != FSB) 488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB->pred_size() != 2) 490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Calculate the total size of the predicated blocks. 494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Assume instruction counts without branches to be the approximation of 495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // the code size. If the predicated blocks are smaller than a packet size, 496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // approximate the spare room in the packet that could be filled with the 497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // predicated/speculated instructions. 498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TS = 0, FS = 0, Spare = 0; 499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB) { 500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TS = std::distance(FP.TrueB->begin(), FP.TrueB->getFirstTerminator()); 501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TS < HEXAGON_PACKET_SIZE) 502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Spare += HEXAGON_PACKET_SIZE-TS; 503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.FalseB) { 505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FS = std::distance(FP.FalseB->begin(), FP.FalseB->getFirstTerminator()); 506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FS < HEXAGON_PACKET_SIZE) 507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Spare += HEXAGON_PACKET_SIZE-TS; 508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TotalIn = TS+FS; 510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Total number of instructions to be predicated/speculated: " 511f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << TotalIn << ", spare room: " << Spare << "\n"); 512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TotalIn >= SizeLimit+Spare) 513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Count the number of PHI nodes that will need to be updated (converted 516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to MUX). Those can be later converted to predicated instructions, so 517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // they aren't always adding extra cost. 518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // KLUDGE: Also, count the number of predicate register definitions in 519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // each block. The scheduler may increase the pressure of these and cause 520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // expensive spills (e.g. bitmnp01). 521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TotalPh = 0; 522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredDefs = countPredicateDefs(FP.SplitB); 523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.JoinB) { 524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TotalPh = computePhiCost(FP.JoinB); 525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredDefs += countPredicateDefs(FP.JoinB); 526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB && FP.TrueB->succ_size() > 0) { 528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = *FP.TrueB->succ_begin(); 529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TotalPh += computePhiCost(SB); 530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredDefs += countPredicateDefs(SB); 531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.FalseB && FP.FalseB->succ_size() > 0) { 533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = *FP.FalseB->succ_begin(); 534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TotalPh += computePhiCost(SB); 535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredDefs += countPredicateDefs(SB); 536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Total number of extra muxes from converted phis: " 539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << TotalPh << "\n"); 540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TotalIn+TotalPh >= SizeLimit+Spare) 541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Total number of predicate registers: " << PredDefs << "\n"); 544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (PredDefs > 4) 545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 546f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::visitBlock(MachineBasicBlock *B, 552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineLoop *L) { 553f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Changed = false; 554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Visit all dominated blocks from the same loop first, then process B. 556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineDomTreeNode *N = MDT->getNode(B); 557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef GraphTraits<MachineDomTreeNode*> GTN; 558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We will change CFG/DT during this traversal, so take precautions to 559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // avoid problems related to invalidated iterators. In fact, processing 560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // a child C of B cannot cause another child to be removed, but it can 561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // cause a new child to be added (which was a child of C before C itself 562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // was removed. This new child C, however, would have been processed 563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // prior to processing B, so there is no need to process it again. 564f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Simply keep a list of children of B, and traverse that list. 565f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef SmallVector<MachineDomTreeNode*,4> DTNodeVectType; 566f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N)); 567f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (DTNodeVectType::iterator I = Cn.begin(), E = Cn.end(); I != E; ++I) { 568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = (*I)->getBlock(); 569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!Deleted.count(SB)) 570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= visitBlock(SB, L); 571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // When walking down the dominator tree, we want to traverse through 573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // blocks from nested (other) loops, because they can dominate blocks 574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // that are in L. Skip the non-L blocks only after the tree traversal. 575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MLI->getLoopFor(B) != L) 576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FlowPattern FP; 579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!matchFlowPattern(B, L, FP)) 580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!isValid(FP)) { 583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Conversion is not valid\n"); 584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!isProfitable(FP)) { 587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Conversion is not profitable\n"); 588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar convert(FP); 592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar simplifyFlowGraph(FP); 593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) { 598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *HB = L ? L->getHeader() : 0; 599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG((L ? dbgs() << "Visiting loop H:" << PrintMB(HB) 600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : dbgs() << "Visiting function") << "\n"); 601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Changed = false; 602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (L) { 603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I) 604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= visitLoop(*I); 605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *EntryB = GraphTraits<MachineFunction*>::getEntryNode(MFN); 608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= visitBlock(L ? HB : EntryB, L); 609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI) 614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const { 615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Exclude post-increment stores. Those return a value, so we cannot 616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // predicate them. 617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar using namespace Hexagon; 619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar switch (Opc) { 620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Store byte: 621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerb_io: case S4_storerb_rr: 622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerbabs: case S4_storeirb_io: case S2_storerbgp: 623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Store halfword: 624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerh_io: case S4_storerh_rr: 625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerhabs: case S4_storeirh_io: case S2_storerhgp: 626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Store upper halfword: 627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerf_io: case S4_storerf_rr: 628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerfabs: case S2_storerfgp: 629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Store word: 630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storeri_io: case S4_storeri_rr: 631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storeriabs: case S4_storeiri_io: case S2_storerigp: 632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Store doubleword: 633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerd_io: case S4_storerd_rr: 634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerdabs: case S2_storerdgp: 635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI) 642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const { 643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MI->mayLoad() || MI->mayStore()) 644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MI->isCall() || MI->isBarrier() || MI->isBranch()) 646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MI->hasUnmodeledSideEffects()) 648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc, 655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IfTrue) const { 656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Exclude post-increment stores. 657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar using namespace Hexagon; 658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar switch (Opc) { 659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerb_io: 660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S2_pstorerbt_io : S2_pstorerbf_io; 661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storerb_rr: 662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerbt_rr : S4_pstorerbf_rr; 663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerbabs: 664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerbgp: 665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerbt_abs : S4_pstorerbf_abs; 666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storeirb_io: 667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_storeirbt_io : S4_storeirbf_io; 668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerh_io: 669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S2_pstorerht_io : S2_pstorerhf_io; 670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storerh_rr: 671f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerht_rr : S4_pstorerhf_rr; 672f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerhabs: 673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerhgp: 674f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerht_abs : S4_pstorerhf_abs; 675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerf_io: 676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S2_pstorerft_io : S2_pstorerff_io; 677f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storerf_rr: 678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerft_rr : S4_pstorerff_rr; 679f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerfabs: 680f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerfgp: 681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerft_abs : S4_pstorerff_abs; 682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storeirh_io: 683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_storeirht_io : S4_storeirhf_io; 684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storeri_io: 685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S2_pstorerit_io : S2_pstorerif_io; 686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storeri_rr: 687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerit_rr : S4_pstorerif_rr; 688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storeriabs: 689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerigp: 690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerit_abs : S4_pstorerif_abs; 691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storeiri_io: 692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_storeirit_io : S4_storeirif_io; 693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerd_io: 694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S2_pstorerdt_io : S2_pstorerdf_io; 695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S4_storerd_rr: 696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerdt_rr : S4_pstorerdf_rr; 697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerdabs: 698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case S2_storerdgp: 699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return IfTrue ? S4_pstorerdt_abs : S4_pstorerdf_abs; 700f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar llvm_unreachable("Unexpected opcode"); 702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return 0; 703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB, 707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator At, MachineInstr *MI, 708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredR, bool IfTrue) { 709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DebugLoc DL; 710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (At != ToB->end()) 711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DL = At->getDebugLoc(); 712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (!ToB->empty()) 713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DL = ToB->back().getDebugLoc(); 714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (isPredicableStore(MI)) { 718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned COpc = getCondStoreOpcode(Opc, IfTrue); 719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(COpc); 720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstrBuilder MIB = BuildMI(*ToB, At, DL, TII->get(COpc)) 721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(PredR); 722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MIOperands MO(*MI); MO.isValid(); ++MO) 723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MIB.addOperand(*MO); 724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Set memory references. 726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin(); 727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end(); 728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MIB.setMemRefs(MMOBegin, MMOEnd); 729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MI->eraseFromParent(); 731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Opc == Hexagon::J2_jump) { 735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TB = MI->getOperand(0).getMBB(); 736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCInstrDesc &D = TII->get(IfTrue ? Hexagon::J2_jumpt 737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : Hexagon::J2_jumpf); 738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(*ToB, At, DL, D) 739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(PredR) 740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addMBB(TB); 741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MI->eraseFromParent(); 742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Print the offending instruction unconditionally as we are about to 746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // abort. 747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar dbgs() << *MI; 748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar llvm_unreachable("Unexpected instruction"); 749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Predicate/speculate non-branch instructions from FromB into block ToB. 753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Leave the branches alone, they will be handled later. Btw, at this point 754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// FromB should have at most one branch, and it should be unconditional. 755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::predicateBlockNB(MachineBasicBlock *ToB, 756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator At, MachineBasicBlock *FromB, 757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned PredR, bool IfTrue) { 758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Predicating block " << PrintMB(FromB) << "\n"); 759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator End = FromB->getFirstTerminator(); 760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator I, NextI; 761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (I = FromB->begin(); I != End; I = NextI) { 763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(!I->isPHI()); 764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar NextI = std::next(I); 765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (isSafeToSpeculate(&*I)) 766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ToB->splice(At, FromB, I); 767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar predicateInstr(ToB, At, &*I, PredR, IfTrue); 769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB, 774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const FlowPattern &FP) { 775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Visit all PHI nodes in the WhereB block and generate MUX instructions 776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // in the split block. Update the PHI nodes with the values of the MUX. 777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto NonPHI = WhereB->getFirstNonPHI(); 778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto I = WhereB->begin(); I != NonPHI; ++I) { 779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr *PN = &*I; 780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Registers and subregisters corresponding to TrueB, FalseB and SplitB. 781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned TR = 0, TSR = 0, FR = 0, FSR = 0, SR = 0, SSR = 0; 782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (int i = PN->getNumOperands()-2; i > 0; i -= 2) { 783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineOperand &RO = PN->getOperand(i), &BO = PN->getOperand(i+1); 784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (BO.getMBB() == FP.SplitB) 785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SR = RO.getReg(), SSR = RO.getSubReg(); 786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (BO.getMBB() == FP.TrueB) 787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TR = RO.getReg(), TSR = RO.getSubReg(); 788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (BO.getMBB() == FP.FalseB) 789f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FR = RO.getReg(), FSR = RO.getSubReg(); 790f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 791f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PN->RemoveOperand(i+1); 793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PN->RemoveOperand(i); 794f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TR == 0) 796f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TR = SR, TSR = SSR; 797f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (FR == 0) 798f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FR = SR, FSR = SSR; 799f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(TR && FR); 800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 801f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar using namespace Hexagon; 802f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DR = PN->getOperand(0).getReg(); 803f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetRegisterClass *RC = MRI->getRegClass(DR); 804f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCInstrDesc &D = RC == &IntRegsRegClass ? TII->get(C2_mux) 805f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : TII->get(MUX64_rr); 806f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator MuxAt = FP.SplitB->getFirstTerminator(); 808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DebugLoc DL; 809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MuxAt != FP.SplitB->end()) 810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DL = MuxAt->getDebugLoc(); 811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned MuxR = MRI->createVirtualRegister(RC); 812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(*FP.SplitB, MuxAt, DL, D, MuxR) 813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(FP.PredR) 814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(TR, 0, TSR) 815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(FR, 0, FSR); 816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PN->addOperand(MachineOperand::CreateReg(MuxR, false)); 818f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PN->addOperand(MachineOperand::CreateMBB(FP.SplitB)); 819f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 820f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::convert(const FlowPattern &FP) { 824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *TSB = 0, *FSB = 0; 825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator OldTI = FP.SplitB->getFirstTerminator(); 826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(OldTI != FP.SplitB->end()); 827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DebugLoc DL = OldTI->getDebugLoc(); 828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB) { 830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TSB = *FP.TrueB->succ_begin(); 831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar predicateBlockNB(FP.SplitB, OldTI, FP.TrueB, FP.PredR, true); 832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.FalseB) { 834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FSB = *FP.FalseB->succ_begin(); 835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator At = FP.SplitB->getFirstTerminator(); 836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar predicateBlockNB(FP.SplitB, At, FP.FalseB, FP.PredR, false); 837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Regenerate new terminators in the split block and update the successors. 840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // First, remember any information that may be needed later and remove the 841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // existing terminators/successors from the split block. 842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SSB = 0; 843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->erase(OldTI, FP.SplitB->end()); 844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar while (FP.SplitB->succ_size() > 0) { 845f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *T = *FP.SplitB->succ_begin(); 846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // It's possible that the split block had a successor that is not a pre- 847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // dicated block. This could only happen if there was only one block to 848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // be predicated. Example: 849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // split_b: 850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // if (p) jump true_b 851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // jump unrelated2_b 852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // unrelated1_b: 853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // ... 854f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // unrelated2_b: ; can have other predecessors, so it's not "false_b" 855f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // jump other_b 856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // true_b: ; only reachable from split_b, can be predicated 857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // ... 858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Find this successor (SSB) if it exists. 860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (T != FP.TrueB && T != FP.FalseB) { 861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(!SSB); 862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SSB = T; 863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->removeSuccessor(FP.SplitB->succ_begin()); 865f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 866f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 867f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Insert new branches and update the successors of the split block. This 868f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // may create unconditional branches to the layout successor, etc., but 869f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // that will be cleaned up later. For now, make sure that correct code is 870f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // generated. 871f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.JoinB) { 872f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(!SSB || SSB == FP.JoinB); 873f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump)) 874f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addMBB(FP.JoinB); 875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->addSuccessor(FP.JoinB); 876f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 877f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasBranch = false; 878f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB) { 879f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jumpt)) 880f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(FP.PredR) 881f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addMBB(TSB); 882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->addSuccessor(TSB); 883f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HasBranch = true; 884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FSB) { 886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCInstrDesc &D = HasBranch ? TII->get(Hexagon::J2_jump) 887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : TII->get(Hexagon::J2_jumpf); 888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstrBuilder MIB = BuildMI(*FP.SplitB, FP.SplitB->end(), DL, D); 889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!HasBranch) 890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MIB.addReg(FP.PredR); 891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MIB.addMBB(FSB); 892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->addSuccessor(FSB); 893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (SSB) { 895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // This cannot happen if both TSB and FSB are set. [TF]SB are the 896f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // successor blocks of the TrueB and FalseB (or null of the TrueB 897f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // or FalseB block is null). SSB is the potential successor block 898f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // of the SplitB that is neither TrueB nor FalseB. 899f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump)) 900f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addMBB(SSB); 901f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->addSuccessor(SSB); 902f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 903f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 904f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 905f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // What is left to do is to update the PHI nodes that could have entries 906f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // referring to predicated blocks. 907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.JoinB) { 908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar updatePhiNodes(FP.JoinB, FP); 909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TSB) 911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar updatePhiNodes(TSB, FP); 912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FSB) 913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar updatePhiNodes(FSB, FP); 914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Nothing to update in SSB, since SSB's predecessors haven't changed. 915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 918f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) { 920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Removing block " << PrintMB(B) << "\n"); 921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 922f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Transfer the immediate dominator information from B to its descendants. 923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineDomTreeNode *N = MDT->getNode(B); 924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineDomTreeNode *IDN = N->getIDom(); 925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (IDN) { 926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *IDB = IDN->getBlock(); 927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef GraphTraits<MachineDomTreeNode*> GTN; 928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef SmallVector<MachineDomTreeNode*,4> DTNodeVectType; 929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N)); 930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (DTNodeVectType::iterator I = Cn.begin(), E = Cn.end(); I != E; ++I) { 931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = (*I)->getBlock(); 932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MDT->changeImmediateDominator(SB, IDB); 933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar while (B->succ_size() > 0) 937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar B->removeSuccessor(B->succ_begin()); 938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto I = B->pred_begin(), E = B->pred_end(); I != E; ++I) 940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (*I)->removeSuccessor(B, true); 941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Deleted.insert(B); 943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MDT->eraseNode(B); 944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MFN->erase(B->getIterator()); 945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 948f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) { 949f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Removing phi nodes from block " << PrintMB(B) << "\n"); 950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator I, NextI, NonPHI = B->getFirstNonPHI(); 951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (I = B->begin(); I != NonPHI; I = NextI) { 952f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar NextI = std::next(I); 953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr *PN = &*I; 954f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(PN->getNumOperands() == 3 && "Invalid phi node"); 955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineOperand &UO = PN->getOperand(1); 956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned UseR = UO.getReg(), UseSR = UO.getSubReg(); 957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DefR = PN->getOperand(0).getReg(); 958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned NewR = UseR; 959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (UseSR) { 960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // MRI.replaceVregUsesWith does not allow to update the subregister, 961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // so instead of doing the use-iteration here, create a copy into a 962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // "non-subregistered" register. 963de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const DebugLoc &DL = PN->getDebugLoc(); 964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const TargetRegisterClass *RC = MRI->getRegClass(DefR); 965f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar NewR = MRI->createVirtualRegister(RC); 966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar NonPHI = BuildMI(*B, NonPHI, DL, TII->get(TargetOpcode::COPY), NewR) 967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addReg(UseR, 0, UseSR); 968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MRI->replaceRegWith(DefR, NewR); 970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar B->erase(I); 971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 974f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 975f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::replacePhiEdges(MachineBasicBlock *OldB, 976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *NewB) { 977f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto I = OldB->succ_begin(), E = OldB->succ_end(); I != E; ++I) { 978f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = *I; 979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator P, N = SB->getFirstNonPHI(); 980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (P = SB->begin(); P != N; ++P) { 981de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr &PN = *P; 982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (MIOperands MO(PN); MO.isValid(); ++MO) 983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MO->isMBB() && MO->getMBB() == OldB) 984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MO->setMBB(NewB); 985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 988f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 989f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB, 991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SuccB) { 992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Merging blocks " << PrintMB(PredB) << " and " 993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << PrintMB(SuccB) << "\n"); 994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool TermOk = hasUncondBranch(SuccB); 995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar eliminatePhis(SuccB); 996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TII->RemoveBranch(*PredB); 997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredB->removeSuccessor(SuccB); 998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredB->splice(PredB->end(), SuccB, SuccB->begin(), SuccB->end()); 999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::succ_iterator I, E = SuccB->succ_end(); 1000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (I = SuccB->succ_begin(); I != E; ++I) 1001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredB->addSuccessor(*I); 1002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredB->normalizeSuccProbs(); 1003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar replacePhiEdges(SuccB, PredB); 1004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar removeBlock(SuccB); 1005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TermOk) 1006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PredB->updateTerminator(); 1007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1009f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1010f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonEarlyIfConversion::simplifyFlowGraph(const FlowPattern &FP) { 1011f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.TrueB) 1012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar removeBlock(FP.TrueB); 1013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.FalseB) 1014f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar removeBlock(FP.FalseB); 1015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1016f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FP.SplitB->updateTerminator(); 1017f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FP.SplitB->succ_size() != 1) 1018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 1019f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *SB = *FP.SplitB->succ_begin(); 1021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (SB->pred_size() != 1) 1022f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 1023f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1024f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // By now, the split block has only one successor (SB), and SB has only 1025f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // one predecessor. We can try to merge them. We will need to update ter- 1026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // minators in FP.Split+SB, and that requires working AnalyzeBranch, which 1027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // fails on Hexagon for blocks that have EH_LABELs. However, if SB ends 1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // with an unconditional branch, we won't need to touch the terminators. 1029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!hasEHLabel(SB) || hasUncondBranch(SB)) 1030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar mergeBlocks(FP.SplitB, SB); 1031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1034f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) { 1035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipFunction(*MF.getFunction())) 1036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &ST = MF.getSubtarget(); 1039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TII = ST.getInstrInfo(); 1040f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TRI = ST.getRegisterInfo(); 1041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MFN = &MF; 1042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MRI = &MF.getRegInfo(); 1043f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MDT = &getAnalysis<MachineDominatorTree>(); 1044f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MLI = &getAnalysis<MachineLoopInfo>(); 1045f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MBPI = EnableHexagonBP ? &getAnalysis<MachineBranchProbabilityInfo>() : 1046f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar nullptr; 1047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Deleted.clear(); 1049f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Changed = false; 1050f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1051f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end(); I != E; ++I) 1052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= visitLoop(*I); 1053f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= visitLoop(0); 1054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1055f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Changed; 1056f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1057f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 1059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Public Constructor Functions 1060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 1061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createHexagonEarlyIfConversion() { 1062f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return new HexagonEarlyIfConversion(); 1063f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1065