PPCCTRLoops.cpp revision f3ef5332fa3f4d5ec72c178a2b19dac363a19383
199f823f94374917174f96a7689955b8463db6816Hal Finkel//===-- PPCCTRLoops.cpp - Identify and generate CTR loops -----------------===// 299f823f94374917174f96a7689955b8463db6816Hal Finkel// 399f823f94374917174f96a7689955b8463db6816Hal Finkel// The LLVM Compiler Infrastructure 499f823f94374917174f96a7689955b8463db6816Hal Finkel// 599f823f94374917174f96a7689955b8463db6816Hal Finkel// This file is distributed under the University of Illinois Open Source 699f823f94374917174f96a7689955b8463db6816Hal Finkel// License. See LICENSE.TXT for details. 799f823f94374917174f96a7689955b8463db6816Hal Finkel// 899f823f94374917174f96a7689955b8463db6816Hal Finkel//===----------------------------------------------------------------------===// 999f823f94374917174f96a7689955b8463db6816Hal Finkel// 1099f823f94374917174f96a7689955b8463db6816Hal Finkel// This pass identifies loops where we can generate the PPC branch instructions 1199f823f94374917174f96a7689955b8463db6816Hal Finkel// that decrement and test the count register (CTR) (bdnz and friends). 1299f823f94374917174f96a7689955b8463db6816Hal Finkel// 1399f823f94374917174f96a7689955b8463db6816Hal Finkel// The pattern that defines the induction variable can changed depending on 1499f823f94374917174f96a7689955b8463db6816Hal Finkel// prior optimizations. For example, the IndVarSimplify phase run by 'opt' 1599f823f94374917174f96a7689955b8463db6816Hal Finkel// normalizes induction variables, and the Loop Strength Reduction pass 1699f823f94374917174f96a7689955b8463db6816Hal Finkel// run by 'llc' may also make changes to the induction variable. 1799f823f94374917174f96a7689955b8463db6816Hal Finkel// 1899f823f94374917174f96a7689955b8463db6816Hal Finkel// Criteria for CTR loops: 1999f823f94374917174f96a7689955b8463db6816Hal Finkel// - Countable loops (w/ ind. var for a trip count) 2099f823f94374917174f96a7689955b8463db6816Hal Finkel// - Try inner-most loops first 2199f823f94374917174f96a7689955b8463db6816Hal Finkel// - No nested CTR loops. 2299f823f94374917174f96a7689955b8463db6816Hal Finkel// - No function calls in loops. 2399f823f94374917174f96a7689955b8463db6816Hal Finkel// 2499f823f94374917174f96a7689955b8463db6816Hal Finkel//===----------------------------------------------------------------------===// 2599f823f94374917174f96a7689955b8463db6816Hal Finkel 26b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Transforms/Scalar.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "PPC.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "PPCTargetMachine.h" 29b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/ADT/STLExtras.h" 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Statistic.h" 31b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Analysis/LoopInfo.h" 32b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Analysis/ScalarEvolutionExpander.h" 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Analysis/TargetLibraryInfo.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 35b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/IR/DerivedTypes.h" 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Dominators.h" 37bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel#include "llvm/IR/InlineAsm.h" 38b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/IR/Instructions.h" 39b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/IR/IntrinsicInst.h" 40b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/IR/Module.h" 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueHandle.h" 42d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/PassSupport.h" 43b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Support/CommandLine.h" 4499f823f94374917174f96a7689955b8463db6816Hal Finkel#include "llvm/Support/Debug.h" 4599f823f94374917174f96a7689955b8463db6816Hal Finkel#include "llvm/Support/raw_ostream.h" 46b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Transforms/Utils/BasicBlockUtils.h" 47b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include "llvm/Transforms/Utils/Local.h" 484e6b24ffcfafbc0c5eda1bb89163ccd56f394fdfHal Finkel#include "llvm/Transforms/Utils/LoopUtils.h" 49b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 50e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#ifndef NDEBUG 51e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#include "llvm/CodeGen/MachineDominators.h" 52e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#include "llvm/CodeGen/MachineFunction.h" 53e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#include "llvm/CodeGen/MachineFunctionPass.h" 54e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#include "llvm/CodeGen/MachineRegisterInfo.h" 55e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#endif 56e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 5799f823f94374917174f96a7689955b8463db6816Hal Finkel#include <algorithm> 58b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#include <vector> 5999f823f94374917174f96a7689955b8463db6816Hal Finkel 6099f823f94374917174f96a7689955b8463db6816Hal Finkelusing namespace llvm; 6199f823f94374917174f96a7689955b8463db6816Hal Finkel 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "ctrloops" 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 64b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#ifndef NDEBUG 65b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkelstatic cl::opt<int> CTRLoopLimit("ppc-max-ctrloop", cl::Hidden, cl::init(-1)); 66b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#endif 67b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 6899f823f94374917174f96a7689955b8463db6816Hal FinkelSTATISTIC(NumCTRLoops, "Number of loops converted to CTR loops"); 6999f823f94374917174f96a7689955b8463db6816Hal Finkel 7096848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszeknamespace llvm { 7196848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek void initializePPCCTRLoopsPass(PassRegistry&); 72e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#ifndef NDEBUG 73e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel void initializePPCCTRLoopsVerifyPass(PassRegistry&); 74e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#endif 7596848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek} 7696848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek 7799f823f94374917174f96a7689955b8463db6816Hal Finkelnamespace { 78b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel struct PPCCTRLoops : public FunctionPass { 79b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 80b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#ifndef NDEBUG 81b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel static int Counter; 82b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#endif 8399f823f94374917174f96a7689955b8463db6816Hal Finkel 8499f823f94374917174f96a7689955b8463db6816Hal Finkel public: 85b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel static char ID; 8699f823f94374917174f96a7689955b8463db6816Hal Finkel 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PPCCTRLoops() : FunctionPass(ID), TM(nullptr) { 88b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel initializePPCCTRLoopsPass(*PassRegistry::getPassRegistry()); 89b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel } 90b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel PPCCTRLoops(PPCTargetMachine &TM) : FunctionPass(ID), TM(&TM) { 9196848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek initializePPCCTRLoopsPass(*PassRegistry::getPassRegistry()); 9296848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek } 9399f823f94374917174f96a7689955b8463db6816Hal Finkel 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnFunction(Function &F) override; 9599f823f94374917174f96a7689955b8463db6816Hal Finkel 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<LoopInfoWrapperPass>(); 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addPreserved<LoopInfoWrapperPass>(); 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addPreserved<DominatorTreeWrapperPass>(); 101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addRequired<ScalarEvolutionWrapperPass>(); 10299f823f94374917174f96a7689955b8463db6816Hal Finkel } 10399f823f94374917174f96a7689955b8463db6816Hal Finkel 10499f823f94374917174f96a7689955b8463db6816Hal Finkel private: 105c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel bool mightUseCTR(const Triple &TT, BasicBlock *BB); 106b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel bool convertToCTRLoop(Loop *L); 10708f92c98ac1cdb43ec35653536c89964401d936cHal Finkel 10899f823f94374917174f96a7689955b8463db6816Hal Finkel private: 109b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel PPCTargetMachine *TM; 110b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel LoopInfo *LI; 111b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel ScalarEvolution *SE; 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL; 113b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel DominatorTree *DT; 114b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel const TargetLibraryInfo *LibInfo; 115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool PreserveLCSSA; 11699f823f94374917174f96a7689955b8463db6816Hal Finkel }; 117b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 118b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel char PPCCTRLoops::ID = 0; 119b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#ifndef NDEBUG 120b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel int PPCCTRLoops::Counter = 0; 121b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#endif 122e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 123e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#ifndef NDEBUG 124e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel struct PPCCTRLoopsVerify : public MachineFunctionPass { 125e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel public: 126e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel static char ID; 127e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 128e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel PPCCTRLoopsVerify() : MachineFunctionPass(ID) { 129e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel initializePPCCTRLoopsVerifyPass(*PassRegistry::getPassRegistry()); 130e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 131e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 133e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel AU.addRequired<MachineDominatorTree>(); 134e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MachineFunctionPass::getAnalysisUsage(AU); 135e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 136e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnMachineFunction(MachineFunction &MF) override; 138e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 139e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel private: 140e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MachineDominatorTree *MDT; 141e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel }; 142e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 143e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel char PPCCTRLoopsVerify::ID = 0; 144e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#endif // NDEBUG 14599f823f94374917174f96a7689955b8463db6816Hal Finkel} // end anonymous namespace 14699f823f94374917174f96a7689955b8463db6816Hal Finkel 14796848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof ParzyszekINITIALIZE_PASS_BEGIN(PPCCTRLoops, "ppc-ctr-loops", "PowerPC CTR Loops", 14896848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek false, false) 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 150ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) 15296848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof ParzyszekINITIALIZE_PASS_END(PPCCTRLoops, "ppc-ctr-loops", "PowerPC CTR Loops", 15396848dfc465c8c7f156a562c246803ebefcf21cfKrzysztof Parzyszek false, false) 15499f823f94374917174f96a7689955b8463db6816Hal Finkel 155b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal FinkelFunctionPass *llvm::createPPCCTRLoops(PPCTargetMachine &TM) { 156b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return new PPCCTRLoops(TM); 15799f823f94374917174f96a7689955b8463db6816Hal Finkel} 15899f823f94374917174f96a7689955b8463db6816Hal Finkel 159e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#ifndef NDEBUG 160e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal FinkelINITIALIZE_PASS_BEGIN(PPCCTRLoopsVerify, "ppc-ctr-loops-verify", 161e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel "PowerPC CTR Loops Verify", false, false) 162e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal FinkelINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 163e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal FinkelINITIALIZE_PASS_END(PPCCTRLoopsVerify, "ppc-ctr-loops-verify", 164e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel "PowerPC CTR Loops Verify", false, false) 165e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 166e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal FinkelFunctionPass *llvm::createPPCCTRLoopsVerify() { 167e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return new PPCCTRLoopsVerify(); 168e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel} 169e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#endif // NDEBUG 170e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 171b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkelbool PPCCTRLoops::runOnFunction(Function &F) { 172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DL = &F.getParent()->getDataLayout(); 176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>(); 177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LibInfo = TLIP ? &TLIP->getTLI() : nullptr; 178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PreserveLCSSA = mustPreserveAnalysisID(LCSSAID); 17999f823f94374917174f96a7689955b8463db6816Hal Finkel 180b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel bool MadeChange = false; 18199f823f94374917174f96a7689955b8463db6816Hal Finkel 182b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel for (LoopInfo::iterator I = LI->begin(), E = LI->end(); 18399f823f94374917174f96a7689955b8463db6816Hal Finkel I != E; ++I) { 184b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Loop *L = *I; 185b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!L->getParentLoop()) 186b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel MadeChange |= convertToCTRLoop(L); 18799f823f94374917174f96a7689955b8463db6816Hal Finkel } 18899f823f94374917174f96a7689955b8463db6816Hal Finkel 189b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; 19099f823f94374917174f96a7689955b8463db6816Hal Finkel} 19199f823f94374917174f96a7689955b8463db6816Hal Finkel 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isLargeIntegerTy(bool Is32Bit, Type *Ty) { 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IntegerType *ITy = dyn_cast<IntegerType>(Ty)) 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ITy->getBitWidth() > (Is32Bit ? 32U : 64U); 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Determining the address of a TLS variable results in a function call in 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// certain TLS models. 201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool memAddrUsesCTR(const PPCTargetMachine *TM, 202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Value *MemAddr) { 203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const auto *GV = dyn_cast<GlobalValue>(MemAddr); 204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!GV) { 205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Recurse to check for constants that refer to TLS global variables. 206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (const auto *CV = dyn_cast<Constant>(MemAddr)) 207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const auto &CO : CV->operands()) 208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (memAddrUsesCTR(TM, CO)) 209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!GV->isThreadLocal()) 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!TM) 217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TLSModel::Model Model = TM->getTLSModel(GV); 219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Model == TLSModel::GeneralDynamic || Model == TLSModel::LocalDynamic; 220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 222c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkelbool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { 223c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); 224c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel J != JE; ++J) { 225c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (CallInst *CI = dyn_cast<CallInst>(J)) { 226bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel if (InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledValue())) { 227bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel // Inline ASM is okay, unless it clobbers the ctr register. 228bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel InlineAsm::ConstraintInfoVector CIV = IA->ParseConstraints(); 229bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel for (unsigned i = 0, ie = CIV.size(); i < ie; ++i) { 230bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel InlineAsm::ConstraintInfo &C = CIV[i]; 231bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel if (C.Type != InlineAsm::isInput) 232bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel for (unsigned j = 0, je = C.Codes.size(); j < je; ++j) 233bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel if (StringRef(C.Codes[j]).equals_lower("{ctr}")) 234bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel return true; 235bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel } 236bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel 237bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel continue; 238bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel } 239bf0bc3b2a2e11ff7e79b881ca82324fe17919a97Hal Finkel 240c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!TM) 241c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetLowering *TLI = 243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TM->getSubtargetImpl(*BB->getParent())->getTargetLowering(); 244c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 245c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (Function *F = CI->getCalledFunction()) { 246c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // Most intrinsics don't become function calls, but some might. 247c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // sin, cos, exp and log are always calls. 248c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel unsigned Opcode; 249c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (F->getIntrinsicID() != Intrinsic::not_intrinsic) { 250c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel switch (F->getIntrinsicID()) { 251c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel default: continue; 252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If we have a call to ppc_is_decremented_ctr_nonzero, or ppc_mtctr 253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // we're definitely using CTR. 254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case Intrinsic::ppc_is_decremented_ctr_nonzero: 255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case Intrinsic::ppc_mtctr: 256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 257c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 258c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel// VisualStudio defines setjmp as _setjmp 259c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel#if defined(_MSC_VER) && defined(setjmp) && \ 260c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel !defined(setjmp_undefined_for_msvc) 261c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel# pragma push_macro("setjmp") 262c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel# undef setjmp 263c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel# define setjmp_undefined_for_msvc 264c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel#endif 265c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 266c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::setjmp: 267c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 268c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc) 269c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // let's return it to _setjmp state 270c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel# pragma pop_macro("setjmp") 271c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel# undef setjmp_undefined_for_msvc 272c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel#endif 273c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 274c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::longjmp: 2758d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel 2768d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel // Exclude eh_sjlj_setjmp; we don't need to exclude eh_sjlj_longjmp 2778d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel // because, although it does clobber the counter register, the 2788d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel // control can't then return to inside the loop unless there is also 2798d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel // an eh_sjlj_setjmp. 2808d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel case Intrinsic::eh_sjlj_setjmp: 2818d7435e9b1319c6e748a06c0b41a4c3de82ec750Hal Finkel 282c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::memcpy: 283c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::memmove: 284c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::memset: 285c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::powi: 286c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::log: 287c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::log2: 288c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::log10: 289c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::exp: 290c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::exp2: 291c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::pow: 292c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::sin: 293c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::cos: 294c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 29566d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel case Intrinsic::copysign: 29666d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel if (CI->getArgOperand(0)->getType()->getScalarType()-> 29766d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel isPPC_FP128Ty()) 29866d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel return true; 29966d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel else 30066d1fa6f4b443ac9f8bcea5d1f71a73ada733a42Hal Finkel continue; // ISD::FCOPYSIGN is never a library call. 301c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::sqrt: Opcode = ISD::FSQRT; break; 302c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::floor: Opcode = ISD::FFLOOR; break; 303c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::ceil: Opcode = ISD::FCEIL; break; 304c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::trunc: Opcode = ISD::FTRUNC; break; 305c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::rint: Opcode = ISD::FRINT; break; 306c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case Intrinsic::nearbyint: Opcode = ISD::FNEARBYINT; break; 30741418d17cced656f91038b2482bc9d173b4974b0Hal Finkel case Intrinsic::round: Opcode = ISD::FROUND; break; 308c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 309c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 310c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 311c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // PowerPC does not use [US]DIVREM or other library calls for 312c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // operations on regular types which are not otherwise library calls 313c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // (i.e. soft float or atomics). If adapting for targets that do, 314c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // additional care is required here. 315c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 316c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel LibFunc::Func Func; 317c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!F->hasLocalLinkage() && F->hasName() && LibInfo && 318c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel LibInfo->getLibFunc(F->getName(), Func) && 319c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel LibInfo->hasOptimizedCodeGen(Func)) { 320c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // Non-read-only functions are never treated as intrinsics. 321c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!CI->onlyReadsMemory()) 322c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 323c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 324c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // Conversion happens only for FP calls. 325c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!CI->getArgOperand(0)->getType()->isFloatingPointTy()) 326c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 327c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 328c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel switch (Func) { 329c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel default: return true; 330c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::copysign: 331c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::copysignf: 332c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel continue; // ISD::FCOPYSIGN is never a library call. 33330cbccb029b01738202bd04341b1cbf68a7814c9Hal Finkel case LibFunc::copysignl: 33430cbccb029b01738202bd04341b1cbf68a7814c9Hal Finkel return true; 335c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::fabs: 336c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::fabsf: 337c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::fabsl: 338c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel continue; // ISD::FABS is never a library call. 339c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::sqrt: 340c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::sqrtf: 341c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::sqrtl: 342c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FSQRT; break; 343c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::floor: 344c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::floorf: 345c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::floorl: 346c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FFLOOR; break; 347c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::nearbyint: 348c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::nearbyintf: 349c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::nearbyintl: 350c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FNEARBYINT; break; 351c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::ceil: 352c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::ceilf: 353c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::ceill: 354c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FCEIL; break; 355c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::rint: 356c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::rintf: 357c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::rintl: 358c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FRINT; break; 35941418d17cced656f91038b2482bc9d173b4974b0Hal Finkel case LibFunc::round: 36041418d17cced656f91038b2482bc9d173b4974b0Hal Finkel case LibFunc::roundf: 36141418d17cced656f91038b2482bc9d173b4974b0Hal Finkel case LibFunc::roundl: 36241418d17cced656f91038b2482bc9d173b4974b0Hal Finkel Opcode = ISD::FROUND; break; 363c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::trunc: 364c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::truncf: 365c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel case LibFunc::truncl: 366c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel Opcode = ISD::FTRUNC; break; 367c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 368c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &DL = CI->getModule()->getDataLayout(); 370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MVT VTy = TLI->getSimpleValueType(DL, CI->getArgOperand(0)->getType(), 371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar true); 372c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (VTy == MVT::Other) 373c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 375c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (TLI->isOperationLegalOrCustom(Opcode, VTy)) 376c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel continue; 377c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel else if (VTy.isVector() && 378c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel TLI->isOperationLegalOrCustom(Opcode, VTy.getScalarType())) 379c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel continue; 380c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 381c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 382c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 383c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 384c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 385c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 386c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } else if (isa<BinaryOperator>(J) && 387c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel J->getType()->getScalarType()->isPPC_FP128Ty()) { 388c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // Most operations on ppc_f128 values become calls. 389c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 390c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } else if (isa<UIToFPInst>(J) || isa<SIToFPInst>(J) || 391c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel isa<FPToUIInst>(J) || isa<FPToSIInst>(J)) { 392c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel CastInst *CI = cast<CastInst>(J); 393c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (CI->getSrcTy()->getScalarType()->isPPC_FP128Ty() || 394c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel CI->getDestTy()->getScalarType()->isPPC_FP128Ty() || 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isLargeIntegerTy(TT.isArch32Bit(), CI->getSrcTy()->getScalarType()) || 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isLargeIntegerTy(TT.isArch32Bit(), CI->getDestTy()->getScalarType())) 397c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (isLargeIntegerTy(TT.isArch32Bit(), 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines J->getType()->getScalarType()) && 40040be73bed71a69853720a7f0609cb1f2f77dc3bdHal Finkel (J->getOpcode() == Instruction::UDiv || 40140be73bed71a69853720a7f0609cb1f2f77dc3bdHal Finkel J->getOpcode() == Instruction::SDiv || 40240be73bed71a69853720a7f0609cb1f2f77dc3bdHal Finkel J->getOpcode() == Instruction::URem || 40340be73bed71a69853720a7f0609cb1f2f77dc3bdHal Finkel J->getOpcode() == Instruction::SRem)) { 40440be73bed71a69853720a7f0609cb1f2f77dc3bdHal Finkel return true; 405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (TT.isArch32Bit() && 406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isLargeIntegerTy(false, J->getType()->getScalarType()) && 407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (J->getOpcode() == Instruction::Shl || 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines J->getOpcode() == Instruction::AShr || 409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines J->getOpcode() == Instruction::LShr)) { 410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Only on PPC32, for 128-bit integers (specifically not 64-bit 411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // integers), these might be runtime calls. 412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 413c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } else if (isa<IndirectBrInst>(J) || isa<InvokeInst>(J)) { 414c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // On PowerPC, indirect jumps use the counter register. 415c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 416c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } else if (SwitchInst *SI = dyn_cast<SwitchInst>(J)) { 417c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!TM) 418c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetLowering *TLI = 420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TM->getSubtargetImpl(*BB->getParent())->getTargetLowering(); 421c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SI->getNumCases() + 1 >= (unsigned)TLI->getMinimumJumpTableEntries()) 423c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return true; 424c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Value *Operand : J->operands()) 426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (memAddrUsesCTR(TM, Operand)) 427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 428c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel } 429c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 430c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return false; 431c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel} 432c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 433b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkelbool PPCCTRLoops::convertToCTRLoop(Loop *L) { 434b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel bool MadeChange = false; 43599f823f94374917174f96a7689955b8463db6816Hal Finkel 436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Triple TT = 437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Triple(L->getHeader()->getParent()->getParent()->getTargetTriple()); 438b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!TT.isArch32Bit() && !TT.isArch64Bit()) 439b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; // Unknown arch. type. 4401448d06156728712f47e5a71fac8e8edc0aba73bHal Finkel 441b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // Process nested loops first. 442b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) { 443b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel MadeChange |= convertToCTRLoop(*I); 444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DEBUG(dbgs() << "Nested loop converted\n"); 445b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel } 4461448d06156728712f47e5a71fac8e8edc0aba73bHal Finkel 447b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // If a nested loop has been converted, then we can't convert this loop. 448b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (MadeChange) 449b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; 450b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 451b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#ifndef NDEBUG 452b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // Stop trying after reaching the limit (if any). 453b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel int Limit = CTRLoopLimit; 454b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (Limit >= 0) { 455b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (Counter >= CTRLoopLimit) 456b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return false; 457b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Counter++; 458b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel } 459b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel#endif 460b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 461b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // We don't want to spill/restore the counter register, and so we don't 462b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // want to use the counter register if the loop contains calls. 463b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel for (Loop::block_iterator I = L->block_begin(), IE = L->block_end(); 464c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel I != IE; ++I) 465c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (mightUseCTR(TT, *I)) 466c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel return MadeChange; 46799f823f94374917174f96a7689955b8463db6816Hal Finkel 468b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel SmallVector<BasicBlock*, 4> ExitingBlocks; 469b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel L->getExitingBlocks(ExitingBlocks); 470b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BasicBlock *CountedExitBlock = nullptr; 472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SCEV *ExitCount = nullptr; 473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BranchInst *CountedExitBranch = nullptr; 4746227d5c690504c7ada5780c00a635b282c46e275Craig Topper for (SmallVectorImpl<BasicBlock *>::iterator I = ExitingBlocks.begin(), 475b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel IE = ExitingBlocks.end(); I != IE; ++I) { 476b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel const SCEV *EC = SE->getExitCount(L, *I); 477b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel DEBUG(dbgs() << "Exit Count for " << *L << " from block " << 478b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel (*I)->getName() << ": " << *EC << "\n"); 479b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (isa<SCEVCouldNotCompute>(EC)) 480b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 481b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (const SCEVConstant *ConstEC = dyn_cast<SCEVConstant>(EC)) { 482b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (ConstEC->getValue()->isZero()) 483b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 484b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel } else if (!SE->isLoopInvariant(EC, L)) 485b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 486b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 487b5f7b0f9780cd1bc6f948b194adfc57176d41711Hal Finkel if (SE->getTypeSizeInBits(EC->getType()) > (TT.isArch64Bit() ? 64 : 32)) 488b5f7b0f9780cd1bc6f948b194adfc57176d41711Hal Finkel continue; 489b5f7b0f9780cd1bc6f948b194adfc57176d41711Hal Finkel 490b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // We now have a loop-invariant count of loop iterations (which is not the 491b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // constant zero) for which we know that this loop will not exit via this 492b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // exisiting block. 493b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 494b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // We need to make sure that this block will run on every loop iteration. 495b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // For this to be true, we must dominate all blocks with backedges. Such 496b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // blocks are in-loop predecessors to the header block. 497b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel bool NotAlways = false; 498b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel for (pred_iterator PI = pred_begin(L->getHeader()), 499b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel PIE = pred_end(L->getHeader()); PI != PIE; ++PI) { 500b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!L->contains(*PI)) 501b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 50299f823f94374917174f96a7689955b8463db6816Hal Finkel 503b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!DT->dominates(*I, *PI)) { 504b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel NotAlways = true; 505b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel break; 50699f823f94374917174f96a7689955b8463db6816Hal Finkel } 50799f823f94374917174f96a7689955b8463db6816Hal Finkel } 50899f823f94374917174f96a7689955b8463db6816Hal Finkel 509b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (NotAlways) 510b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 51199f823f94374917174f96a7689955b8463db6816Hal Finkel 512b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // Make sure this blocks ends with a conditional branch. 513b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Instruction *TI = (*I)->getTerminator(); 514b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!TI) 515b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 51699f823f94374917174f96a7689955b8463db6816Hal Finkel 517b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 518b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!BI->isConditional()) 51999f823f94374917174f96a7689955b8463db6816Hal Finkel continue; 52099f823f94374917174f96a7689955b8463db6816Hal Finkel 521b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountedExitBranch = BI; 522b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel } else 523b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel continue; 52499f823f94374917174f96a7689955b8463db6816Hal Finkel 525b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // Note that this block may not be the loop latch block, even if the loop 526b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // has a latch block. 527b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountedExitBlock = *I; 528b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel ExitCount = EC; 529b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel break; 53099f823f94374917174f96a7689955b8463db6816Hal Finkel } 53199f823f94374917174f96a7689955b8463db6816Hal Finkel 532b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!CountedExitBlock) 533b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; 534b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 535b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel BasicBlock *Preheader = L->getLoopPreheader(); 536c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel 537c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // If we don't have a preheader, then insert one. If we already have a 538c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // preheader, then we can use it (except if the preheader contains a use of 539c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // the CTR register because some such uses might be reordered by the 540c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel // selection DAG after the mtctr instruction). 541c482454e3cc2a33a2cf2d1cf0881c7c5e2641c80Hal Finkel if (!Preheader || mightUseCTR(TT, Preheader)) 542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Preheader = InsertPreheaderForLoop(L, DT, LI, PreserveLCSSA); 543b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!Preheader) 544b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; 545b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 546b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel DEBUG(dbgs() << "Preheader for exit count: " << Preheader->getName() << "\n"); 547b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 548b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // Insert the count into the preheader and replace the condition used by the 549b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // selected branch. 550b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel MadeChange = true; 551b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 5524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SCEVExpander SCEVE(*SE, Preheader->getModule()->getDataLayout(), "loopcnt"); 553b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel LLVMContext &C = SE->getContext(); 554b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Type *CountType = TT.isArch64Bit() ? Type::getInt64Ty(C) : 555b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Type::getInt32Ty(C); 556b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!ExitCount->getType()->isPointerTy() && 557b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel ExitCount->getType() != CountType) 558b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel ExitCount = SE->getZeroExtendExpr(ExitCount, CountType); 559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ExitCount = SE->getAddExpr(ExitCount, SE->getOne(CountType)); 560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Value *ECValue = 561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SCEVE.expandCodeFor(ExitCount, CountType, Preheader->getTerminator()); 562b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 563b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel IRBuilder<> CountBuilder(Preheader->getTerminator()); 564b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Module *M = Preheader->getParent()->getParent(); 565b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Value *MTCTRFunc = Intrinsic::getDeclaration(M, Intrinsic::ppc_mtctr, 566b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountType); 567b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountBuilder.CreateCall(MTCTRFunc, ECValue); 568b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 569b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel IRBuilder<> CondBuilder(CountedExitBranch); 570b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Value *DecFunc = 571b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Intrinsic::getDeclaration(M, Intrinsic::ppc_is_decremented_ctr_nonzero); 5726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *NewCond = CondBuilder.CreateCall(DecFunc, {}); 573b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel Value *OldCond = CountedExitBranch->getCondition(); 574b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountedExitBranch->setCondition(NewCond); 575b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 576b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // The false branch must exit the loop. 577b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel if (!L->contains(CountedExitBranch->getSuccessor(0))) 578b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel CountedExitBranch->swapSuccessors(); 579b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel 580b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // The old condition may be dead now, and may have even created a dead PHI 581b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel // (the original induction variable). 582b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel RecursivelyDeleteTriviallyDeadInstructions(OldCond); 583b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel DeleteDeadPHIs(CountedExitBlock); 5849887ec31e630ede8541dee1d90c44a1efb63c417Hal Finkel 585b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel ++NumCTRLoops; 586b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel return MadeChange; 587b1fd3cd78f8acd21dbf514b75fef991827c343b6Hal Finkel} 5889887ec31e630ede8541dee1d90c44a1efb63c417Hal Finkel 589e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#ifndef NDEBUG 590e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkelstatic bool clobbersCTR(const MachineInstr *MI) { 591e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 592e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel const MachineOperand &MO = MI->getOperand(i); 593e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (MO.isReg()) { 594e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8)) 595e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return true; 596e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } else if (MO.isRegMask()) { 597e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8)) 598e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return true; 599e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 600e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 601e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 602e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return false; 603e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel} 604e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 605e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkelstatic bool verifyCTRBranch(MachineBasicBlock *MBB, 606e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MachineBasicBlock::iterator I) { 607e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MachineBasicBlock::iterator BI = I; 608e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel SmallSet<MachineBasicBlock *, 16> Visited; 609e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel SmallVector<MachineBasicBlock *, 8> Preds; 610e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel bool CheckPreds; 611e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 612e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (I == MBB->begin()) { 613e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel Visited.insert(MBB); 614e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel goto queue_preds; 615e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } else 616e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel --I; 617e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 618e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkelcheck_block: 619e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel Visited.insert(MBB); 620e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (I == MBB->end()) 621e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel goto queue_preds; 622e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 623e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel CheckPreds = true; 624e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel for (MachineBasicBlock::iterator IE = MBB->begin();; --I) { 625e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel unsigned Opc = I->getOpcode(); 62685c08b059ce4248ee739e756cf717a9b429e2ec2Hal Finkel if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) { 627e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel CheckPreds = false; 628e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel break; 629e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 630e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 631e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (I != BI && clobbersCTR(I)) { 632e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel DEBUG(dbgs() << "BB#" << MBB->getNumber() << " (" << 633e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MBB->getFullName() << ") instruction " << *I << 634e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel " clobbers CTR, invalidating " << "BB#" << 635e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel BI->getParent()->getNumber() << " (" << 636e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel BI->getParent()->getFullName() << ") instruction " << 637e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel *BI << "\n"); 638e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return false; 639e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 640e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 641e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (I == IE) 642e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel break; 643e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 644e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 645e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (!CheckPreds && Preds.empty()) 646e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return true; 647e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 648e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (CheckPreds) { 649e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkelqueue_preds: 650e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (MachineFunction::iterator(MBB) == MBB->getParent()->begin()) { 651e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel DEBUG(dbgs() << "Unable to find a MTCTR instruction for BB#" << 652e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel BI->getParent()->getNumber() << " (" << 653e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel BI->getParent()->getFullName() << ") instruction " << 654e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel *BI << "\n"); 655e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return false; 656e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 657e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 658e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), 659e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel PIE = MBB->pred_end(); PI != PIE; ++PI) 660e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel Preds.push_back(*PI); 661e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 662e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 663e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel do { 664e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MBB = Preds.pop_back_val(); 665e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (!Visited.count(MBB)) { 666e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel I = MBB->getLastNonDebugInstr(); 667e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel goto check_block; 668e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 669e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } while (!Preds.empty()); 670e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 671e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return true; 672e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel} 673e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 674e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkelbool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) { 675e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MDT = &getAnalysis<MachineDominatorTree>(); 676e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 677e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel // Verify that all bdnz/bdz instructions are dominated by a loop mtctr before 678e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel // any other instructions that might clobber the ctr register. 679e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel for (MachineFunction::iterator I = MF.begin(), IE = MF.end(); 680e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel I != IE; ++I) { 681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock *MBB = &*I; 682e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (!MDT->isReachableFromEntry(MBB)) 683e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel continue; 684e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 685e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel for (MachineBasicBlock::iterator MII = MBB->getFirstTerminator(), 686e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel MIIE = MBB->end(); MII != MIIE; ++MII) { 687e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel unsigned Opc = MII->getOpcode(); 688e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ || 689e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel Opc == PPC::BDZ8 || Opc == PPC::BDZ) 690e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel if (!verifyCTRBranch(MBB, MII)) 691e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel llvm_unreachable("Invalid PPC CTR loop!"); 692e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 693e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel } 694e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel 695e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel return false; 696e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel} 697e50c8c1f81a38f0ecebafa5dc60a163814a9713aHal Finkel#endif // NDEBUG 698