131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- PPCInstrInfo.cpp - PowerPC Instruction Information ----------------===// 2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 3f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// The LLVM Compiler Infrastructure 4f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 8f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===// 9f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// 10f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// This file contains the PowerPC implementation of the TargetInstrInfo class. 11f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// 12f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===// 13f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman 1416e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCInstrInfo.h" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/PPCPredicates.h" 1659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "PPC.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "PPCHazardRecognizers.h" 18f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson#include "PPCInstrBuilder.h" 197194aaf738a1b89441635340403f1c5b06ae18efBill Wendling#include "PPCMachineFunctionInfo.h" 20b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris Lattner#include "PPCTargetMachine.h" 215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#include "llvm/ADT/Statistic.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 237a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFrameInfo.h" 245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#include "llvm/CodeGen/MachineFunctionPass.h" 25f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/MachineInstrBuilder.h" 267a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineMemOperand.h" 27243296690ec78fc918762bd73896b09e26537f47Jakob Stoklund Olesen#include "llvm/CodeGen/MachineRegisterInfo.h" 284d989ac93ce608057fb6b13a4068264ab037ecd5Hal Finkel#include "llvm/CodeGen/PseudoSourceValue.h" 2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCAsmInfo.h" 30880d0f6018b6928bdcad291be60c801238619955Bill Wendling#include "llvm/Support/CommandLine.h" 31dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 323e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 33dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 34f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman 35860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel#define GET_INSTRMAP_INFO 364db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR 3722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "PPCGenInstrInfo.inc" 3822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng 3982bcd236937b378e56e46bdde9c17a3ea3377068Dan Gohmanusing namespace llvm; 40880d0f6018b6928bdcad291be60c801238619955Bill Wendling 4109fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkelstatic cl:: 427255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkelopt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, 437255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel cl::desc("Disable analysis for CTR loops")); 4409fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel 4587c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkelstatic cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt", 464029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkelcl::desc("Disable compare instruction optimization"), cl::Hidden); 474029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel 48b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris LattnerPPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm) 494db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP), 5080ada583f3b40ffb201e54cd57c42f9518039c9eBill Wendling TM(tm), RI(*TM.getSubtargetImpl()) {} 51b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris Lattner 522da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 532da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick/// this target when scheduling the DAG. 542da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer( 552da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const TargetMachine *TM, 562da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const ScheduleDAG *DAG) const { 57c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel unsigned Directive = TM->getSubtarget<PPCSubtarget>().getDarwinDirective(); 58621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 || 59621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) { 60768c65f677af3f05c2e94982043f90a1bfaceda5Hal Finkel const InstrItineraryData *II = TM->getInstrItineraryData(); 615b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel return new PPCScoreboardHazardRecognizer(II, DAG); 62c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel } 6364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel 64a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen return TargetInstrInfo::CreateTargetHazardRecognizer(TM, DAG); 652da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick} 662da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 6764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel/// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer 6864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel/// to use for this target when scheduling the DAG. 6964c34e253563a8ba6b41fbce2bb020632cf65961Hal FinkelScheduleHazardRecognizer *PPCInstrInfo::CreateTargetPostRAHazardRecognizer( 7064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel const InstrItineraryData *II, 7164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel const ScheduleDAG *DAG) const { 7264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel unsigned Directive = TM.getSubtarget<PPCSubtarget>().getDarwinDirective(); 7364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel 7464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel // Most subtargets use a PPC970 recognizer. 75621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel if (Directive != PPC::DIR_440 && Directive != PPC::DIR_A2 && 76621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel Directive != PPC::DIR_E500mc && Directive != PPC::DIR_E5500) { 77041399aad5a3d93c2dc9d2b70cb9b87d4a987eceBenjamin Kramer assert(TM.getInstrInfo() && "No InstrInfo?"); 7864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel 7980ada583f3b40ffb201e54cd57c42f9518039c9eBill Wendling return new PPCHazardRecognizer970(TM); 8064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel } 8164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel 824d989ac93ce608057fb6b13a4068264ab037ecd5Hal Finkel return new PPCScoreboardHazardRecognizer(II, DAG); 8364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel} 847164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen 857164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen// Detect 32 -> 64-bit extensions where we may reuse the low sub-register. 867164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesenbool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI, 877164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen unsigned &SrcReg, unsigned &DstReg, 887164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen unsigned &SubIdx) const { 897164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen switch (MI.getOpcode()) { 907164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen default: return false; 917164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen case PPC::EXTSW: 927164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen case PPC::EXTSW_32_64: 937164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen SrcReg = MI.getOperand(1).getReg(); 947164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen DstReg = MI.getOperand(0).getReg(); 957164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen SubIdx = PPC::sub_32; 967164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen return true; 977164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen } 987164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen} 997164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen 1006e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickunsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 1019c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner int &FrameIndex) const { 102f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Note: This list must be kept consistent with LoadRegFromStackSlot. 103408396014742a05cad1c91949d2226169e3f9d80Chris Lattner switch (MI->getOpcode()) { 104408396014742a05cad1c91949d2226169e3f9d80Chris Lattner default: break; 105408396014742a05cad1c91949d2226169e3f9d80Chris Lattner case PPC::LD: 106408396014742a05cad1c91949d2226169e3f9d80Chris Lattner case PPC::LWZ: 107408396014742a05cad1c91949d2226169e3f9d80Chris Lattner case PPC::LFS: 108408396014742a05cad1c91949d2226169e3f9d80Chris Lattner case PPC::LFD: 109f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::RESTORE_CR: 110f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::LVX: 111f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::RESTORE_VRSAVE: 112f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Check for the operands added by addFrameReference (the immediate is the 113f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // offset which defaults to 0). 114d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() && 115d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman MI->getOperand(2).isFI()) { 1168aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner FrameIndex = MI->getOperand(2).getIndex(); 117408396014742a05cad1c91949d2226169e3f9d80Chris Lattner return MI->getOperand(0).getReg(); 118408396014742a05cad1c91949d2226169e3f9d80Chris Lattner } 119408396014742a05cad1c91949d2226169e3f9d80Chris Lattner break; 120408396014742a05cad1c91949d2226169e3f9d80Chris Lattner } 121408396014742a05cad1c91949d2226169e3f9d80Chris Lattner return 0; 1226524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner} 123408396014742a05cad1c91949d2226169e3f9d80Chris Lattner 1246e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickunsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 1256524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner int &FrameIndex) const { 126f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Note: This list must be kept consistent with StoreRegToStackSlot. 1276524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner switch (MI->getOpcode()) { 1286524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner default: break; 1293b478b31e297208ef2c9f74750a8a603eb3726fbNate Begeman case PPC::STD: 1306524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner case PPC::STW: 1316524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner case PPC::STFS: 1326524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner case PPC::STFD: 133f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::SPILL_CR: 134f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::STVX: 135f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel case PPC::SPILL_VRSAVE: 136f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Check for the operands added by addFrameReference (the immediate is the 137f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // offset which defaults to 0). 138d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() && 139d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman MI->getOperand(2).isFI()) { 1408aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner FrameIndex = MI->getOperand(2).getIndex(); 1416524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner return MI->getOperand(0).getReg(); 1426524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner } 1436524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner break; 1446524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner } 1456524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner return 0; 1466524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner} 147408396014742a05cad1c91949d2226169e3f9d80Chris Lattner 148043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner// commuteInstruction - We can commute rlwimi instructions, but only if the 149043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner// rotate amt is zero. We also have to munge the immediates a bit. 15058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan ChengMachineInstr * 15158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan ChengPPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const { 1528e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineFunction &MF = *MI->getParent()->getParent(); 1538e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman 154043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Normal instructions can be commuted the obvious way. 155171a8adf3168aee2f739f91c1800e9025892c7b5Hal Finkel if (MI->getOpcode() != PPC::RLWIMI && 156171a8adf3168aee2f739f91c1800e9025892c7b5Hal Finkel MI->getOpcode() != PPC::RLWIMIo) 157a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen return TargetInstrInfo::commuteInstruction(MI, NewMI); 1586e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 159043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Cannot commute if it has a non-zero rotate count. 1609a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner if (MI->getOperand(3).getImm() != 0) 161043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner return 0; 1626e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 163043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // If we have a zero rotate count, we have: 164043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // M = mask(MB,ME) 165043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Op0 = (Op1 & ~M) | (Op2 & M) 166043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Change this to: 167043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // M = mask((ME+1)&31, (MB-1)&31) 168043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Op0 = (Op2 & ~M) | (Op1 & M) 169043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner 170043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Swap op1/op2 171a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng unsigned Reg0 = MI->getOperand(0).getReg(); 172043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner unsigned Reg1 = MI->getOperand(1).getReg(); 173043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner unsigned Reg2 = MI->getOperand(2).getReg(); 1746ce7dc2a97260eea5fba414332796464912b9359Evan Cheng bool Reg1IsKill = MI->getOperand(1).isKill(); 1756ce7dc2a97260eea5fba414332796464912b9359Evan Cheng bool Reg2IsKill = MI->getOperand(2).isKill(); 17658dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng bool ChangeReg0 = false; 177a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng // If machine instrs are no longer in two-address forms, update 178a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng // destination register as well. 179a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng if (Reg0 == Reg1) { 180a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng // Must be two address instruction! 181e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng assert(MI->getDesc().getOperandConstraint(0, MCOI::TIED_TO) && 182a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng "Expecting a two-address instruction!"); 183a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng Reg2IsKill = false; 18458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng ChangeReg0 = true; 18558dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng } 18658dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng 18758dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng // Masks. 18858dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng unsigned MB = MI->getOperand(4).getImm(); 18958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng unsigned ME = MI->getOperand(5).getImm(); 19058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng 19158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng if (NewMI) { 19258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng // Create a new instruction. 19358dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); 19458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng bool Reg0IsDead = MI->getOperand(0).isDead(); 195d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling return BuildMI(MF, MI->getDebugLoc(), MI->getDesc()) 196587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead)) 197587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(Reg2, getKillRegState(Reg2IsKill)) 198587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(Reg1, getKillRegState(Reg1IsKill)) 19958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng .addImm((ME+1) & 31) 20058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng .addImm((MB-1) & 31); 201a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng } 20258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng 20358dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng if (ChangeReg0) 20458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng MI->getOperand(0).setReg(Reg2); 205e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner MI->getOperand(2).setReg(Reg1); 206e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner MI->getOperand(1).setReg(Reg2); 207f73823000e2d5d6e1cf65bdf5a107297e18d35fbChris Lattner MI->getOperand(2).setIsKill(Reg1IsKill); 208f73823000e2d5d6e1cf65bdf5a107297e18d35fbChris Lattner MI->getOperand(1).setIsKill(Reg2IsKill); 2096e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 210043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner // Swap the mask around. 2119a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner MI->getOperand(4).setImm((ME+1) & 31); 2129a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner MI->getOperand(5).setImm((MB-1) & 31); 213043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner return MI; 214043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner} 215bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner 2166e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickvoid PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, 217bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner MachineBasicBlock::iterator MI) const { 218c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 219d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling BuildMI(MBB, MI, DL, get(PPC::NOP)); 220bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner} 221c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 222c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 223c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner// Branch analysis. 22499f823f94374917174f96a7689955b8463db6816Hal Finkel// Note: If the condition register is set to CTR or CTR8 then this is a 22599f823f94374917174f96a7689955b8463db6816Hal Finkel// BDNZ (imm == 1) or BDZ (imm == 0) branch. 226c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattnerbool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 227c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner MachineBasicBlock *&FBB, 228dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng SmallVectorImpl<MachineOperand> &Cond, 229dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng bool AllowModify) const { 23099f823f94374917174f96a7689955b8463db6816Hal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 23199f823f94374917174f96a7689955b8463db6816Hal Finkel 232c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // If the block has no terminators, it just falls into the block after it. 233c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner MachineBasicBlock::iterator I = MBB.end(); 23493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 23593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return false; 23693d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 23793d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen while (I->isDebugValue()) { 23893d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 23993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return false; 24093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 24193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen } 24293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (!isUnpredicatedTerminator(I)) 243c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return false; 244c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 245c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Get the last instruction in the block. 246c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner MachineInstr *LastInst = I; 2476e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 248c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // If there is only one terminator instruction, process it. 249bfd2ec4a8ef51ebe982363a7e8d7156fdb3827d8Evan Cheng if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 250c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner if (LastInst->getOpcode() == PPC::B) { 25182ae933e55839713ea039e7c6353483b14dc5724Evan Cheng if (!LastInst->getOperand(0).isMBB()) 25282ae933e55839713ea039e7c6353483b14dc5724Evan Cheng return true; 2538aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner TBB = LastInst->getOperand(0).getMBB(); 254c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return false; 255289c2d5f4566d8d7722e3934f4763d3df92886f3Chris Lattner } else if (LastInst->getOpcode() == PPC::BCC) { 25682ae933e55839713ea039e7c6353483b14dc5724Evan Cheng if (!LastInst->getOperand(2).isMBB()) 25782ae933e55839713ea039e7c6353483b14dc5724Evan Cheng return true; 258c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Block ends with fall-through condbranch. 2598aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner TBB = LastInst->getOperand(2).getMBB(); 260c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner Cond.push_back(LastInst->getOperand(0)); 261c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner Cond.push_back(LastInst->getOperand(1)); 2627c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner return false; 26399f823f94374917174f96a7689955b8463db6816Hal Finkel } else if (LastInst->getOpcode() == PPC::BDNZ8 || 26499f823f94374917174f96a7689955b8463db6816Hal Finkel LastInst->getOpcode() == PPC::BDNZ) { 26599f823f94374917174f96a7689955b8463db6816Hal Finkel if (!LastInst->getOperand(0).isMBB()) 26699f823f94374917174f96a7689955b8463db6816Hal Finkel return true; 2677255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel if (DisableCTRLoopAnal) 26809fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel return true; 26999f823f94374917174f96a7689955b8463db6816Hal Finkel TBB = LastInst->getOperand(0).getMBB(); 27099f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateImm(1)); 27199f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR, 27299f823f94374917174f96a7689955b8463db6816Hal Finkel true)); 27399f823f94374917174f96a7689955b8463db6816Hal Finkel return false; 27499f823f94374917174f96a7689955b8463db6816Hal Finkel } else if (LastInst->getOpcode() == PPC::BDZ8 || 27599f823f94374917174f96a7689955b8463db6816Hal Finkel LastInst->getOpcode() == PPC::BDZ) { 27699f823f94374917174f96a7689955b8463db6816Hal Finkel if (!LastInst->getOperand(0).isMBB()) 27799f823f94374917174f96a7689955b8463db6816Hal Finkel return true; 2787255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel if (DisableCTRLoopAnal) 27909fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel return true; 28099f823f94374917174f96a7689955b8463db6816Hal Finkel TBB = LastInst->getOperand(0).getMBB(); 28199f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateImm(0)); 28299f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR, 28399f823f94374917174f96a7689955b8463db6816Hal Finkel true)); 28499f823f94374917174f96a7689955b8463db6816Hal Finkel return false; 285c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner } 28699f823f94374917174f96a7689955b8463db6816Hal Finkel 287c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Otherwise, don't know what this is. 288c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return true; 289c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner } 2906e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 291c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Get the instruction before it if it's a terminator. 292c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner MachineInstr *SecondLastInst = I; 293c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 294c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // If there are three terminators, we don't know what sort of block this is. 295c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner if (SecondLastInst && I != MBB.begin() && 296bfd2ec4a8ef51ebe982363a7e8d7156fdb3827d8Evan Cheng isUnpredicatedTerminator(--I)) 297c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return true; 2986e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 299289c2d5f4566d8d7722e3934f4763d3df92886f3Chris Lattner // If the block ends with PPC::B and PPC:BCC, handle it. 3006e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick if (SecondLastInst->getOpcode() == PPC::BCC && 301c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner LastInst->getOpcode() == PPC::B) { 30282ae933e55839713ea039e7c6353483b14dc5724Evan Cheng if (!SecondLastInst->getOperand(2).isMBB() || 30382ae933e55839713ea039e7c6353483b14dc5724Evan Cheng !LastInst->getOperand(0).isMBB()) 30482ae933e55839713ea039e7c6353483b14dc5724Evan Cheng return true; 3058aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner TBB = SecondLastInst->getOperand(2).getMBB(); 306c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner Cond.push_back(SecondLastInst->getOperand(0)); 307c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner Cond.push_back(SecondLastInst->getOperand(1)); 3088aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner FBB = LastInst->getOperand(0).getMBB(); 309c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return false; 31099f823f94374917174f96a7689955b8463db6816Hal Finkel } else if ((SecondLastInst->getOpcode() == PPC::BDNZ8 || 31199f823f94374917174f96a7689955b8463db6816Hal Finkel SecondLastInst->getOpcode() == PPC::BDNZ) && 31299f823f94374917174f96a7689955b8463db6816Hal Finkel LastInst->getOpcode() == PPC::B) { 31399f823f94374917174f96a7689955b8463db6816Hal Finkel if (!SecondLastInst->getOperand(0).isMBB() || 31499f823f94374917174f96a7689955b8463db6816Hal Finkel !LastInst->getOperand(0).isMBB()) 31599f823f94374917174f96a7689955b8463db6816Hal Finkel return true; 3167255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel if (DisableCTRLoopAnal) 31709fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel return true; 31899f823f94374917174f96a7689955b8463db6816Hal Finkel TBB = SecondLastInst->getOperand(0).getMBB(); 31999f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateImm(1)); 32099f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR, 32199f823f94374917174f96a7689955b8463db6816Hal Finkel true)); 32299f823f94374917174f96a7689955b8463db6816Hal Finkel FBB = LastInst->getOperand(0).getMBB(); 32399f823f94374917174f96a7689955b8463db6816Hal Finkel return false; 32499f823f94374917174f96a7689955b8463db6816Hal Finkel } else if ((SecondLastInst->getOpcode() == PPC::BDZ8 || 32599f823f94374917174f96a7689955b8463db6816Hal Finkel SecondLastInst->getOpcode() == PPC::BDZ) && 32699f823f94374917174f96a7689955b8463db6816Hal Finkel LastInst->getOpcode() == PPC::B) { 32799f823f94374917174f96a7689955b8463db6816Hal Finkel if (!SecondLastInst->getOperand(0).isMBB() || 32899f823f94374917174f96a7689955b8463db6816Hal Finkel !LastInst->getOperand(0).isMBB()) 32999f823f94374917174f96a7689955b8463db6816Hal Finkel return true; 3307255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel if (DisableCTRLoopAnal) 33109fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel return true; 33299f823f94374917174f96a7689955b8463db6816Hal Finkel TBB = SecondLastInst->getOperand(0).getMBB(); 33399f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateImm(0)); 33499f823f94374917174f96a7689955b8463db6816Hal Finkel Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR, 33599f823f94374917174f96a7689955b8463db6816Hal Finkel true)); 33699f823f94374917174f96a7689955b8463db6816Hal Finkel FBB = LastInst->getOperand(0).getMBB(); 33799f823f94374917174f96a7689955b8463db6816Hal Finkel return false; 338c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner } 3396e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 34013e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen // If the block ends with two PPC:Bs, handle it. The second one is not 34113e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen // executed, so remove it. 3426e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick if (SecondLastInst->getOpcode() == PPC::B && 34313e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen LastInst->getOpcode() == PPC::B) { 34482ae933e55839713ea039e7c6353483b14dc5724Evan Cheng if (!SecondLastInst->getOperand(0).isMBB()) 34582ae933e55839713ea039e7c6353483b14dc5724Evan Cheng return true; 3468aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner TBB = SecondLastInst->getOperand(0).getMBB(); 34713e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen I = LastInst; 348dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng if (AllowModify) 349dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng I->eraseFromParent(); 35013e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen return false; 35113e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen } 35213e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen 353c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Otherwise, can't handle this. 354c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner return true; 355c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner} 356c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 357b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Chengunsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 358c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner MachineBasicBlock::iterator I = MBB.end(); 359b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng if (I == MBB.begin()) return 0; 360c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner --I; 36193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen while (I->isDebugValue()) { 36293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 36393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return 0; 36493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 36593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen } 36699f823f94374917174f96a7689955b8463db6816Hal Finkel if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC && 36799f823f94374917174f96a7689955b8463db6816Hal Finkel I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ && 36899f823f94374917174f96a7689955b8463db6816Hal Finkel I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ) 369b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng return 0; 3706e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 371c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Remove the branch. 372c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner I->eraseFromParent(); 3736e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 374c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner I = MBB.end(); 375c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 376b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng if (I == MBB.begin()) return 1; 377c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner --I; 37899f823f94374917174f96a7689955b8463db6816Hal Finkel if (I->getOpcode() != PPC::BCC && 37999f823f94374917174f96a7689955b8463db6816Hal Finkel I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ && 38099f823f94374917174f96a7689955b8463db6816Hal Finkel I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ) 381b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng return 1; 3826e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 383c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner // Remove the branch. 384c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner I->eraseFromParent(); 385b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng return 2; 386c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner} 387c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 388b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Chengunsigned 389b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan ChengPPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 390b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng MachineBasicBlock *FBB, 3913bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings const SmallVectorImpl<MachineOperand> &Cond, 3923bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings DebugLoc DL) const { 3932dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner // Shouldn't be a fall through. 3942dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 3956e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick assert((Cond.size() == 2 || Cond.size() == 0) && 39654108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner "PPC branch conditions have two components!"); 3976e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 39899f823f94374917174f96a7689955b8463db6816Hal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 39999f823f94374917174f96a7689955b8463db6816Hal Finkel 40054108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner // One-way branch. 4012dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner if (FBB == 0) { 40254108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner if (Cond.empty()) // Unconditional branch 4033bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(PPC::B)).addMBB(TBB); 40499f823f94374917174f96a7689955b8463db6816Hal Finkel else if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8) 40599f823f94374917174f96a7689955b8463db6816Hal Finkel BuildMI(&MBB, DL, get(Cond[0].getImm() ? 40699f823f94374917174f96a7689955b8463db6816Hal Finkel (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) : 40799f823f94374917174f96a7689955b8463db6816Hal Finkel (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB); 40854108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner else // Conditional branch 4093bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(PPC::BCC)) 41018258c640466274c26e89016e361ec411ff78520Chris Lattner .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 411b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng return 1; 4122dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner } 4136e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 414879d09cf130f3760a08865913c04d9ff328fad5fChris Lattner // Two-way Conditional Branch. 41599f823f94374917174f96a7689955b8463db6816Hal Finkel if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8) 41699f823f94374917174f96a7689955b8463db6816Hal Finkel BuildMI(&MBB, DL, get(Cond[0].getImm() ? 41799f823f94374917174f96a7689955b8463db6816Hal Finkel (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) : 41899f823f94374917174f96a7689955b8463db6816Hal Finkel (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB); 41999f823f94374917174f96a7689955b8463db6816Hal Finkel else 42099f823f94374917174f96a7689955b8463db6816Hal Finkel BuildMI(&MBB, DL, get(PPC::BCC)) 42199f823f94374917174f96a7689955b8463db6816Hal Finkel .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); 4223bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(PPC::B)).addMBB(FBB); 423b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng return 2; 424c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner} 425c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner 426ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel// Select analysis. 427ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkelbool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB, 428ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const SmallVectorImpl<MachineOperand> &Cond, 429ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned TrueReg, unsigned FalseReg, 430ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel int &CondCycles, int &TrueCycles, int &FalseCycles) const { 431ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (!TM.getSubtargetImpl()->hasISEL()) 432ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return false; 433ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 434ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (Cond.size() != 2) 435ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return false; 436ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 437ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // If this is really a bdnz-like condition, then it cannot be turned into a 438ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // select. 439ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8) 440ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return false; 441ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 442ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // Check register classes. 443ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 444ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const TargetRegisterClass *RC = 445ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); 446ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (!RC) 447ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return false; 448ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 449ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // isel is for regular integer GPRs only. 450ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (!PPC::GPRCRegClass.hasSubClassEq(RC) && 451ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) && 452ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel !PPC::G8RCRegClass.hasSubClassEq(RC) && 453ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) 454ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return false; 455ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 456ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // FIXME: These numbers are for the A2, how well they work for other cores is 457ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // an open question. On the A2, the isel instruction has a 2-cycle latency 458ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // but single-cycle throughput. These numbers are used in combination with 459ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // the MispredictPenalty setting from the active SchedMachineModel. 460ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel CondCycles = 1; 461ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel TrueCycles = 1; 462ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel FalseCycles = 1; 463ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 464ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel return true; 465ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel} 466ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 467ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkelvoid PPCInstrInfo::insertSelect(MachineBasicBlock &MBB, 468ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel MachineBasicBlock::iterator MI, DebugLoc dl, 469ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned DestReg, 470ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const SmallVectorImpl<MachineOperand> &Cond, 471ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned TrueReg, unsigned FalseReg) const { 472ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel assert(Cond.size() == 2 && 473ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel "PPC branch conditions have two components!"); 474ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 475ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel assert(TM.getSubtargetImpl()->hasISEL() && 476ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel "Cannot insert select on target without ISEL support"); 477ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 478ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // Get the register classes. 479ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 480ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const TargetRegisterClass *RC = 481ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); 482ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel assert(RC && "TrueReg and FalseReg must have overlapping register classes"); 483ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel 484ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) || 485ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel PPC::G8RC_NOX0RegClass.hasSubClassEq(RC); 486ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel assert((Is64Bit || 487ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel PPC::GPRCRegClass.hasSubClassEq(RC) || 488ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) && 489ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel "isel is for regular integer GPRs only"); 490ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 491ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL; 492ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned SelectPred = Cond[0].getImm(); 493ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 494ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned SubIdx; 495ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel bool SwapOps; 496ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel switch (SelectPred) { 497ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel default: llvm_unreachable("invalid predicate for isel"); 498ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_EQ: SubIdx = PPC::sub_eq; SwapOps = false; break; 499ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_NE: SubIdx = PPC::sub_eq; SwapOps = true; break; 500ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_LT: SubIdx = PPC::sub_lt; SwapOps = false; break; 501ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_GE: SubIdx = PPC::sub_lt; SwapOps = true; break; 502ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_GT: SubIdx = PPC::sub_gt; SwapOps = false; break; 503ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_LE: SubIdx = PPC::sub_gt; SwapOps = true; break; 504ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_UN: SubIdx = PPC::sub_un; SwapOps = false; break; 505ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel case PPC::PRED_NU: SubIdx = PPC::sub_un; SwapOps = true; break; 506ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel } 507ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 508ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned FirstReg = SwapOps ? FalseReg : TrueReg, 509ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel SecondReg = SwapOps ? TrueReg : FalseReg; 510ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 511ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // The first input register of isel cannot be r0. If it is a member 512ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // of a register class that can be r0, then copy it first (the 513ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel // register allocator should eliminate the copy). 514ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel if (MRI.getRegClass(FirstReg)->contains(PPC::R0) || 515ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel MRI.getRegClass(FirstReg)->contains(PPC::X0)) { 516ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel const TargetRegisterClass *FirstRC = 517ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel MRI.getRegClass(FirstReg)->contains(PPC::X0) ? 518ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass; 519ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel unsigned OldFirstReg = FirstReg; 520ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel FirstReg = MRI.createVirtualRegister(FirstRC); 521ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel BuildMI(MBB, MI, dl, get(TargetOpcode::COPY), FirstReg) 522ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel .addReg(OldFirstReg); 523ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel } 524ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 525ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel BuildMI(MBB, MI, dl, get(OpCode), DestReg) 526ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel .addReg(FirstReg).addReg(SecondReg) 527ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel .addReg(Cond[1].getReg(), 0, SubIdx); 528ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel} 529ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel 53027689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesenvoid PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 53127689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen MachineBasicBlock::iterator I, DebugLoc DL, 53227689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen unsigned DestReg, unsigned SrcReg, 53327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen bool KillSrc) const { 53427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen unsigned Opc; 53527689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen if (PPC::GPRCRegClass.contains(DestReg, SrcReg)) 53627689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::OR; 53727689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else if (PPC::G8RCRegClass.contains(DestReg, SrcReg)) 53827689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::OR8; 53927689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else if (PPC::F4RCRegClass.contains(DestReg, SrcReg)) 54027689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::FMR; 54127689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else if (PPC::CRRCRegClass.contains(DestReg, SrcReg)) 54227689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::MCRF; 54327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else if (PPC::VRRCRegClass.contains(DestReg, SrcReg)) 54427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::VOR; 54527689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg)) 54627689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen Opc = PPC::CROR; 54727689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else 54827689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen llvm_unreachable("Impossible reg-to-reg copy"); 549d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson 550e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &MCID = get(Opc); 551e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng if (MCID.getNumOperands() == 3) 552e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng BuildMI(MBB, I, DL, MCID, DestReg) 55327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen .addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc)); 55427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen else 555e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc)); 556d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson} 557d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson 5583fd0018af1b692cabfa5a002bf41f1e756aa9ddeHal Finkel// This function returns true if a CR spill is necessary and false otherwise. 5594a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendlingbool 5608e5f2c6f65841542e2a7092553fe42a00048e4c7Dan GohmanPPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, 5618e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman unsigned SrcReg, bool isKill, 5624a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling int FrameIdx, 5634a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling const TargetRegisterClass *RC, 564324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel SmallVectorImpl<MachineInstr*> &NewMIs, 5653f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel bool &NonRI, bool &SpillsVRS) const{ 566f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Note: If additional store instructions are added here, 567f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // update isStoreToStackSlot. 568f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel 569c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 570c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::GPRCRegClass.hasSubClassEq(RC)) { 5717257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) 5727257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel .addReg(SrcReg, 5737257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel getKillRegState(isKill)), 5747257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel FrameIdx)); 575c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) { 5767257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) 5777257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel .addReg(SrcReg, 5787257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel getKillRegState(isKill)), 5797257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel FrameIdx)); 580c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { 58121b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFD)) 582587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(SrcReg, 583587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling getKillRegState(isKill)), 584587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling FrameIdx)); 585c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { 58621b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFS)) 587587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(SrcReg, 588587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling getKillRegState(isKill)), 589587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling FrameIdx)); 590c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { 5917285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CR)) 5927285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel .addReg(SrcReg, 5937285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel getKillRegState(isKill)), 5947285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel FrameIdx)); 5957285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel return true; 596c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { 5970404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray // FIXME: We use CRi here because there is no mtcrf on a bit. Since the 5980404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray // backend currently only uses CR1EQ as an individual bit, this should 5990404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray // not cause any bug. If we need other uses of CR bits, the following 6000404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray // code may be invalid. 6019348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray unsigned Reg = 0; 6026a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT || 6036a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN) 6049348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR0; 6056a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT || 6066a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN) 6079348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR1; 6086a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT || 6096a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN) 6109348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR2; 6116a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT || 6126a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN) 6139348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR3; 6146a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT || 6156a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN) 6169348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR4; 6176a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT || 6186a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN) 6199348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR5; 6206a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT || 6216a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN) 6229348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR6; 6236a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT || 6246a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN) 6259348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR7; 6269348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray 6276e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx, 6283f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel &PPC::CRRCRegClass, NewMIs, NonRI, SpillsVRS); 6299348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray 630c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { 631324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STVX)) 632324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel .addReg(SrcReg, 633324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel getKillRegState(isKill)), 634324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel FrameIdx)); 635324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel NonRI = true; 63610f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { 637b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel assert(TM.getSubtargetImpl()->isDarwin() && 638b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel "VRSAVE only needs spill/restore on Darwin"); 63910f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_VRSAVE)) 64010f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel .addReg(SrcReg, 64110f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel getKillRegState(isKill)), 64210f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel FrameIdx)); 6433f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel SpillsVRS = true; 644f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson } else { 645c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown regclass!"); 646f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson } 6477194aaf738a1b89441635340403f1c5b06ae18efBill Wendling 6487194aaf738a1b89441635340403f1c5b06ae18efBill Wendling return false; 649f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson} 650f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson 651f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid 652f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonPPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 6537194aaf738a1b89441635340403f1c5b06ae18efBill Wendling MachineBasicBlock::iterator MI, 6547194aaf738a1b89441635340403f1c5b06ae18efBill Wendling unsigned SrcReg, bool isKill, int FrameIdx, 655746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 656746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 6578e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineFunction &MF = *MBB.getParent(); 658f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson SmallVector<MachineInstr*, 4> NewMIs; 6597194aaf738a1b89441635340403f1c5b06ae18efBill Wendling 6600cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 6610cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel FuncInfo->setHasSpills(); 6620cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 6633f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel bool NonRI = false, SpillsVRS = false; 6643f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel if (StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs, 6653f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel NonRI, SpillsVRS)) 6667194aaf738a1b89441635340403f1c5b06ae18efBill Wendling FuncInfo->setSpillsCR(); 6677194aaf738a1b89441635340403f1c5b06ae18efBill Wendling 6683f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel if (SpillsVRS) 6693f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel FuncInfo->setSpillsVRSAVE(); 6703f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel 671324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel if (NonRI) 672324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel FuncInfo->setHasNonRISpills(); 673324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 674f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) 675f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson MBB.insert(MI, NewMIs[i]); 6767a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen 6777a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen const MachineFrameInfo &MFI = *MF.getFrameInfo(); 6787a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MachineMemOperand *MMO = 679978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 68059db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner MachineMemOperand::MOStore, 6817a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MFI.getObjectSize(FrameIdx), 6827a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MFI.getObjectAlignment(FrameIdx)); 6837a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen NewMIs.back()->addMemOperand(MF, MMO); 684f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson} 685f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson 686d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkelbool 687d1c321a89ab999b9bb602b0f398ecd4c2022262cBill WendlingPPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, 6888e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman unsigned DestReg, int FrameIdx, 6894a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling const TargetRegisterClass *RC, 690324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel SmallVectorImpl<MachineInstr*> &NewMIs, 6913f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel bool &NonRI, bool &SpillsVRS) const{ 692f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // Note: If additional load instructions are added here, 693f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel // update isLoadFromStackSlot. 694f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel 695c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::GPRCRegClass.hasSubClassEq(RC)) { 696fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), 697fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel DestReg), FrameIdx)); 698c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) { 699fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg), 700fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel FrameIdx)); 701c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { 702d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg), 703f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson FrameIdx)); 704c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { 705d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), 706f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson FrameIdx)); 707c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { 7087285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, 7097285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel get(PPC::RESTORE_CR), DestReg), 7107285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel FrameIdx)); 7117285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel return true; 712c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { 7136e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 7149348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray unsigned Reg = 0; 7156a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller if (DestReg == PPC::CR0LT || DestReg == PPC::CR0GT || 7166a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR0EQ || DestReg == PPC::CR0UN) 7179348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR0; 7186a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR1LT || DestReg == PPC::CR1GT || 7196a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR1EQ || DestReg == PPC::CR1UN) 7209348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR1; 7216a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR2LT || DestReg == PPC::CR2GT || 7226a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR2EQ || DestReg == PPC::CR2UN) 7239348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR2; 7246a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR3LT || DestReg == PPC::CR3GT || 7256a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR3EQ || DestReg == PPC::CR3UN) 7269348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR3; 7276a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR4LT || DestReg == PPC::CR4GT || 7286a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR4EQ || DestReg == PPC::CR4UN) 7299348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR4; 7306a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR5LT || DestReg == PPC::CR5GT || 7316a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR5EQ || DestReg == PPC::CR5UN) 7329348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR5; 7336a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR6LT || DestReg == PPC::CR6GT || 7346a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR6EQ || DestReg == PPC::CR6UN) 7359348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR6; 7366a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller else if (DestReg == PPC::CR7LT || DestReg == PPC::CR7GT || 7376a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller DestReg == PPC::CR7EQ || DestReg == PPC::CR7UN) 7389348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray Reg = PPC::CR7; 7399348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray 7406e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx, 7413f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel &PPC::CRRCRegClass, NewMIs, NonRI, SpillsVRS); 7429348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray 743c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { 744324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LVX), DestReg), 745324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel FrameIdx)); 746324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel NonRI = true; 74710f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { 748b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel assert(TM.getSubtargetImpl()->isDarwin() && 749b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel "VRSAVE only needs spill/restore on Darwin"); 75010f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel NewMIs.push_back(addFrameReference(BuildMI(MF, DL, 75110f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel get(PPC::RESTORE_VRSAVE), 75210f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel DestReg), 75310f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel FrameIdx)); 7543f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel SpillsVRS = true; 755f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson } else { 756c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown regclass!"); 757f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson } 758d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel 759d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel return false; 760f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson} 761f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson 762f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid 763f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonPPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 7647194aaf738a1b89441635340403f1c5b06ae18efBill Wendling MachineBasicBlock::iterator MI, 7657194aaf738a1b89441635340403f1c5b06ae18efBill Wendling unsigned DestReg, int FrameIdx, 766746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 767746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 7688e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman MachineFunction &MF = *MBB.getParent(); 769f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson SmallVector<MachineInstr*, 4> NewMIs; 770c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 771d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling if (MI != MBB.end()) DL = MI->getDebugLoc(); 772324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 773324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 774324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel FuncInfo->setHasSpills(); 775324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 7763f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel bool NonRI = false, SpillsVRS = false; 7773f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel if (LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs, 7783f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel NonRI, SpillsVRS)) 779d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel FuncInfo->setSpillsCR(); 780324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 7813f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel if (SpillsVRS) 7823f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel FuncInfo->setSpillsVRSAVE(); 7833f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel 784324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel if (NonRI) 785324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel FuncInfo->setHasNonRISpills(); 786324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 787f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) 788f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson MBB.insert(MI, NewMIs[i]); 7897a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen 7907a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen const MachineFrameInfo &MFI = *MF.getFrameInfo(); 7917a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MachineMemOperand *MMO = 792978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 79359db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner MachineMemOperand::MOLoad, 7947a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MFI.getObjectSize(FrameIdx), 7957a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen MFI.getObjectAlignment(FrameIdx)); 7967a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen NewMIs.back()->addMemOperand(MF, MMO); 797f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson} 798f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson 799c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattnerbool PPCInstrInfo:: 80044eb65cf58e3ab9b5621ce72256d1621a18aeed7Owen AndersonReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 8017c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner assert(Cond.size() == 2 && "Invalid PPC branch opcode!"); 80299f823f94374917174f96a7689955b8463db6816Hal Finkel if (Cond[1].getReg() == PPC::CTR8 || Cond[1].getReg() == PPC::CTR) 80399f823f94374917174f96a7689955b8463db6816Hal Finkel Cond[0].setImm(Cond[0].getImm() == 0 ? 1 : 0); 80499f823f94374917174f96a7689955b8463db6816Hal Finkel else 80599f823f94374917174f96a7689955b8463db6816Hal Finkel // Leave the CR# the same, but invert the condition. 80699f823f94374917174f96a7689955b8463db6816Hal Finkel Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm())); 8077c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner return false; 808c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner} 80952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray 810839b9096538f790a2bb060547df24703807cb83bHal Finkelbool PPCInstrInfo::FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 811839b9096538f790a2bb060547df24703807cb83bHal Finkel unsigned Reg, MachineRegisterInfo *MRI) const { 812839b9096538f790a2bb060547df24703807cb83bHal Finkel // For some instructions, it is legal to fold ZERO into the RA register field. 813839b9096538f790a2bb060547df24703807cb83bHal Finkel // A zero immediate should always be loaded with a single li. 814839b9096538f790a2bb060547df24703807cb83bHal Finkel unsigned DefOpc = DefMI->getOpcode(); 815839b9096538f790a2bb060547df24703807cb83bHal Finkel if (DefOpc != PPC::LI && DefOpc != PPC::LI8) 816839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 817839b9096538f790a2bb060547df24703807cb83bHal Finkel if (!DefMI->getOperand(1).isImm()) 818839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 819839b9096538f790a2bb060547df24703807cb83bHal Finkel if (DefMI->getOperand(1).getImm() != 0) 820839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 821839b9096538f790a2bb060547df24703807cb83bHal Finkel 822839b9096538f790a2bb060547df24703807cb83bHal Finkel // Note that we cannot here invert the arguments of an isel in order to fold 823839b9096538f790a2bb060547df24703807cb83bHal Finkel // a ZERO into what is presented as the second argument. All we have here 824839b9096538f790a2bb060547df24703807cb83bHal Finkel // is the condition bit, and that might come from a CR-logical bit operation. 825839b9096538f790a2bb060547df24703807cb83bHal Finkel 826839b9096538f790a2bb060547df24703807cb83bHal Finkel const MCInstrDesc &UseMCID = UseMI->getDesc(); 827839b9096538f790a2bb060547df24703807cb83bHal Finkel 828839b9096538f790a2bb060547df24703807cb83bHal Finkel // Only fold into real machine instructions. 829839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseMCID.isPseudo()) 830839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 831839b9096538f790a2bb060547df24703807cb83bHal Finkel 832839b9096538f790a2bb060547df24703807cb83bHal Finkel unsigned UseIdx; 833839b9096538f790a2bb060547df24703807cb83bHal Finkel for (UseIdx = 0; UseIdx < UseMI->getNumOperands(); ++UseIdx) 834839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseMI->getOperand(UseIdx).isReg() && 835839b9096538f790a2bb060547df24703807cb83bHal Finkel UseMI->getOperand(UseIdx).getReg() == Reg) 836839b9096538f790a2bb060547df24703807cb83bHal Finkel break; 837839b9096538f790a2bb060547df24703807cb83bHal Finkel 838839b9096538f790a2bb060547df24703807cb83bHal Finkel assert(UseIdx < UseMI->getNumOperands() && "Cannot find Reg in UseMI"); 839839b9096538f790a2bb060547df24703807cb83bHal Finkel assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg"); 840839b9096538f790a2bb060547df24703807cb83bHal Finkel 841839b9096538f790a2bb060547df24703807cb83bHal Finkel const MCOperandInfo *UseInfo = &UseMCID.OpInfo[UseIdx]; 842839b9096538f790a2bb060547df24703807cb83bHal Finkel 843839b9096538f790a2bb060547df24703807cb83bHal Finkel // We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0 844839b9096538f790a2bb060547df24703807cb83bHal Finkel // register (which might also be specified as a pointer class kind). 845839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseInfo->isLookupPtrRegClass()) { 846839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseInfo->RegClass /* Kind */ != 1) 847839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 848839b9096538f790a2bb060547df24703807cb83bHal Finkel } else { 849839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID && 850839b9096538f790a2bb060547df24703807cb83bHal Finkel UseInfo->RegClass != PPC::G8RC_NOX0RegClassID) 851839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 852839b9096538f790a2bb060547df24703807cb83bHal Finkel } 853839b9096538f790a2bb060547df24703807cb83bHal Finkel 854839b9096538f790a2bb060547df24703807cb83bHal Finkel // Make sure this is not tied to an output register (or otherwise 855839b9096538f790a2bb060547df24703807cb83bHal Finkel // constrained). This is true for ST?UX registers, for example, which 856839b9096538f790a2bb060547df24703807cb83bHal Finkel // are tied to their output registers. 857839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseInfo->Constraints != 0) 858839b9096538f790a2bb060547df24703807cb83bHal Finkel return false; 859839b9096538f790a2bb060547df24703807cb83bHal Finkel 860839b9096538f790a2bb060547df24703807cb83bHal Finkel unsigned ZeroReg; 861839b9096538f790a2bb060547df24703807cb83bHal Finkel if (UseInfo->isLookupPtrRegClass()) { 862839b9096538f790a2bb060547df24703807cb83bHal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 863839b9096538f790a2bb060547df24703807cb83bHal Finkel ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO; 864839b9096538f790a2bb060547df24703807cb83bHal Finkel } else { 865839b9096538f790a2bb060547df24703807cb83bHal Finkel ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ? 866839b9096538f790a2bb060547df24703807cb83bHal Finkel PPC::ZERO8 : PPC::ZERO; 867839b9096538f790a2bb060547df24703807cb83bHal Finkel } 868839b9096538f790a2bb060547df24703807cb83bHal Finkel 869839b9096538f790a2bb060547df24703807cb83bHal Finkel bool DeleteDef = MRI->hasOneNonDBGUse(Reg); 870839b9096538f790a2bb060547df24703807cb83bHal Finkel UseMI->getOperand(UseIdx).setReg(ZeroReg); 871839b9096538f790a2bb060547df24703807cb83bHal Finkel 872839b9096538f790a2bb060547df24703807cb83bHal Finkel if (DeleteDef) 873839b9096538f790a2bb060547df24703807cb83bHal Finkel DefMI->eraseFromParent(); 874839b9096538f790a2bb060547df24703807cb83bHal Finkel 875839b9096538f790a2bb060547df24703807cb83bHal Finkel return true; 876839b9096538f790a2bb060547df24703807cb83bHal Finkel} 877839b9096538f790a2bb060547df24703807cb83bHal Finkel 878da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkelstatic bool MBBDefinesCTR(MachineBasicBlock &MBB) { 879da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end(); 880da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel I != IE; ++I) 881da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel if (I->definesRegister(PPC::CTR) || I->definesRegister(PPC::CTR8)) 882da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel return true; 883da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel return false; 884da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel} 885da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel 886da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// We should make sure that, if we're going to predicate both sides of a 887da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// condition (a diamond), that both sides don't define the counter register. We 888da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// can predicate counter-decrement-based branches, but while that predicates 889da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// the branching, it does not predicate the counter decrement. If we tried to 890da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// merge the triangle into one predicated block, we'd decrement the counter 891da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// twice. 892da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkelbool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, 893da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel unsigned NumT, unsigned ExtraT, 894da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel MachineBasicBlock &FMBB, 895da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel unsigned NumF, unsigned ExtraF, 896da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel const BranchProbability &Probability) const { 897da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB)); 898da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel} 899da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel 900da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel 9017eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isPredicated(const MachineInstr *MI) const { 9024b040294816e49413c739825d801042bc76171a7Hal Finkel // The predicated branches are identified by their type, not really by the 9034b040294816e49413c739825d801042bc76171a7Hal Finkel // explicit presence of a predicate. Furthermore, some of them can be 9044b040294816e49413c739825d801042bc76171a7Hal Finkel // predicated more than once. Because if conversion won't try to predicate 9054b040294816e49413c739825d801042bc76171a7Hal Finkel // any instruction which already claims to be predicated (by returning true 9064b040294816e49413c739825d801042bc76171a7Hal Finkel // here), always return false. In doing so, we let isPredicable() be the 9074b040294816e49413c739825d801042bc76171a7Hal Finkel // final word on whether not the instruction can be (further) predicated. 9084b040294816e49413c739825d801042bc76171a7Hal Finkel 9094b040294816e49413c739825d801042bc76171a7Hal Finkel return false; 9107eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 9117eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9127eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { 9137eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (!MI->isTerminator()) 9147eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 9157eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9167eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // Conditional branch is a special case. 9177eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (MI->isBranch() && !MI->isBarrier()) 9187eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 9197eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9207eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return !isPredicated(MI); 9217eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 9227eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9237eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::PredicateInstruction( 9247eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MachineInstr *MI, 9257eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const SmallVectorImpl<MachineOperand> &Pred) const { 9267eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel unsigned OpC = MI->getOpcode(); 9277eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (OpC == PPC::BLR) { 9287eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) { 9297eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 9307eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MI->setDesc(get(Pred[0].getImm() ? 9317eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR) : 9327eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR))); 9337eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } else { 9347eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MI->setDesc(get(PPC::BCLR)); 9357eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MachineInstrBuilder(*MI->getParent()->getParent(), MI) 9367eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel .addImm(Pred[0].getImm()) 9377eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel .addReg(Pred[1].getReg()); 9387eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 9397eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9407eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 9417eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } else if (OpC == PPC::B) { 9427eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) { 9437eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 9447eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MI->setDesc(get(Pred[0].getImm() ? 9457eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) : 9467eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (isPPC64 ? PPC::BDZ8 : PPC::BDZ))); 9477eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } else { 9487eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MachineBasicBlock *MBB = MI->getOperand(0).getMBB(); 9497eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MI->RemoveOperand(0); 9507eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9517eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MI->setDesc(get(PPC::BCC)); 9527eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel MachineInstrBuilder(*MI->getParent()->getParent(), MI) 9537eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel .addImm(Pred[0].getImm()) 9547eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel .addReg(Pred[1].getReg()) 9557eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel .addMBB(MBB); 9567eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 9577eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9587eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 95990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || 96090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel OpC == PPC::BCTRL || OpC == PPC::BCTRL8) { 96190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) 96290dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel llvm_unreachable("Cannot predicate bctr[l] on the ctr register"); 96390dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel 96490dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8; 96590dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 96690dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) : 96790dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel (setLR ? PPC::BCCTRL : PPC::BCCTR))); 96890dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel MachineInstrBuilder(*MI->getParent()->getParent(), MI) 96990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel .addImm(Pred[0].getImm()) 97090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel .addReg(Pred[1].getReg()); 97190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel return true; 9727eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 9737eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9747eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 9757eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 9767eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9777eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::SubsumesPredicate( 9787eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const SmallVectorImpl<MachineOperand> &Pred1, 9797eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const SmallVectorImpl<MachineOperand> &Pred2) const { 9807eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel assert(Pred1.size() == 2 && "Invalid PPC first predicate"); 9817eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel assert(Pred2.size() == 2 && "Invalid PPC second predicate"); 9827eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9837eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR) 9847eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 9857eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR) 9867eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 9877eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9887eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel PPC::Predicate P1 = (PPC::Predicate) Pred1[0].getImm(); 9897eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel PPC::Predicate P2 = (PPC::Predicate) Pred2[0].getImm(); 9907eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9917eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (P1 == P2) 9927eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 9937eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 9947eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // Does P1 subsume P2, e.g. GE subsumes GT. 9957eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (P1 == PPC::PRED_LE && 9967eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (P2 == PPC::PRED_LT || P2 == PPC::PRED_EQ)) 9977eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 9987eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel if (P1 == PPC::PRED_GE && 9997eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel (P2 == PPC::PRED_GT || P2 == PPC::PRED_EQ)) 10007eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 10017eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10027eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 10037eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 10047eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10057eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::DefinesPredicate(MachineInstr *MI, 10067eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel std::vector<MachineOperand> &Pred) const { 10077eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // Note: At the present time, the contents of Pred from this function is 10087eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // unused by IfConversion. This implementation follows ARM by pushing the 10097eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // CR-defining operand. Because the 'DZ' and 'DNZ' count as types of 10107eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // predicate, instructions defining CTR or CTR8 are also included as 10117eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel // predicate-defining instructions. 10127eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10137eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const TargetRegisterClass *RCs[] = 10147eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass, 10157eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass }; 10167eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10177eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel bool Found = false; 10187eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 10197eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const MachineOperand &MO = MI->getOperand(i); 10204e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) { 10217eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel const TargetRegisterClass *RC = RCs[c]; 10224e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel if (MO.isReg()) { 10234e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel if (MO.isDef() && RC->contains(MO.getReg())) { 10247eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel Pred.push_back(MO); 10257eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel Found = true; 10267eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 10274e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel } else if (MO.isRegMask()) { 10284e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel for (TargetRegisterClass::iterator I = RC->begin(), 10294e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel IE = RC->end(); I != IE; ++I) 10304e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel if (MO.clobbersPhysReg(*I)) { 10314e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel Pred.push_back(MO); 10324e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel Found = true; 10334e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel } 10347eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 10357eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 10367eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 10377eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10387eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return Found; 10397eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 10407eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 10417eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isPredicable(MachineInstr *MI) const { 10427eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel unsigned OpC = MI->getOpcode(); 10437eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel switch (OpC) { 10447eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel default: 10457eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return false; 10467eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel case PPC::B: 10477eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel case PPC::BLR: 104890dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel case PPC::BCTR: 104990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel case PPC::BCTR8: 105090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel case PPC::BCTRL: 105190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel case PPC::BCTRL8: 10527eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel return true; 10537eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel } 10547eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel} 10557eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel 1056860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkelbool PPCInstrInfo::analyzeCompare(const MachineInstr *MI, 1057860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned &SrcReg, unsigned &SrcReg2, 1058860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel int &Mask, int &Value) const { 1059860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned Opc = MI->getOpcode(); 1060860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1061860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel switch (Opc) { 1062860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel default: return false; 1063860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPWI: 1064860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPLWI: 1065860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPDI: 1066860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPLDI: 1067860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel SrcReg = MI->getOperand(1).getReg(); 1068860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel SrcReg2 = 0; 1069860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Value = MI->getOperand(2).getImm(); 1070860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Mask = 0xFFFF; 1071860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return true; 1072860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPW: 1073860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPLW: 1074860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPD: 1075860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::CMPLD: 1076860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::FCMPUS: 1077860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel case PPC::FCMPUD: 1078860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel SrcReg = MI->getOperand(1).getReg(); 1079860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel SrcReg2 = MI->getOperand(2).getReg(); 1080860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return true; 1081860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1082860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel} 108387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel 1084860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkelbool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, 1085860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned SrcReg, unsigned SrcReg2, 1086860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel int Mask, int Value, 1087860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel const MachineRegisterInfo *MRI) const { 10884029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel if (DisableCmpOpt) 10894029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel return false; 10904029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel 1091860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel int OpC = CmpInstr->getOpcode(); 1092860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned CRReg = CmpInstr->getOperand(0).getReg(); 1093b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel 1094b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel // FP record forms set CR1 based on the execption status bits, not a 1095b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel // comparison with zero. 1096b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD) 1097b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel return false; 1098860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1099860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // The record forms set the condition register based on a signed comparison 1100860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // with zero (so says the ISA manual). This is not as straightforward as it 1101860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // seems, however, because this is always a 64-bit comparison on PPC64, even 1102860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // for instructions that are 32-bit in nature (like slw for example). 1103860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // So, on PPC32, for unsigned comparisons, we can use the record forms only 1104860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // for equality checks (as those don't depend on the sign). On PPC64, 1105860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // we are restricted to equality for unsigned 64-bit comparisons and for 1106860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // signed 32-bit comparisons the applicability is more restricted. 1107860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 1108860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW; 1109860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW; 1110860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD; 1111860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1112860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Get the unique definition of SrcReg. 1113860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg); 1114860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (!MI) return false; 1115860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel int MIOpC = MI->getOpcode(); 1116860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1117860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool equalityOnly = false; 1118860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool noSub = false; 1119860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (isPPC64) { 1120860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (is32BitSignedCompare) { 1121860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // We can perform this optimization only if MI is sign-extending. 1122860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (MIOpC == PPC::SRAW || MIOpC == PPC::SRAWo || 1123860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::SRAWI || MIOpC == PPC::SRAWIo || 1124860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::EXTSB || MIOpC == PPC::EXTSBo || 1125860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::EXTSH || MIOpC == PPC::EXTSHo || 1126860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::EXTSW || MIOpC == PPC::EXTSWo) { 1127860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel noSub = true; 1128860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else 1129860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1130860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else if (is32BitUnsignedCompare) { 1131860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // We can perform this optimization, equality only, if MI is 1132860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // zero-extending. 1133860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (MIOpC == PPC::CNTLZW || MIOpC == PPC::CNTLZWo || 1134860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::SLW || MIOpC == PPC::SLWo || 1135860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC == PPC::SRW || MIOpC == PPC::SRWo) { 1136860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel noSub = true; 1137860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel equalityOnly = true; 1138860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else 1139860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1140b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel } else 1141860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel equalityOnly = is64BitUnsignedCompare; 1142b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel } else 1143860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel equalityOnly = is32BitUnsignedCompare; 1144860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1145860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (equalityOnly) { 1146860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // We need to check the uses of the condition register in order to reject 1147860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // non-equality comparisons. 1148860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (MachineRegisterInfo::use_iterator I = MRI->use_begin(CRReg), 1149860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel IE = MRI->use_end(); I != IE; ++I) { 1150860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineInstr *UseMI = &*I; 1151860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (UseMI->getOpcode() == PPC::BCC) { 1152860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned Pred = UseMI->getOperand(0).getImm(); 11538a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel if (Pred != PPC::PRED_EQ && Pred != PPC::PRED_NE) 11548a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel return false; 1155860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else if (UseMI->getOpcode() == PPC::ISEL || 1156860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel UseMI->getOpcode() == PPC::ISEL8) { 1157860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned SubIdx = UseMI->getOperand(3).getSubReg(); 11588a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel if (SubIdx != PPC::sub_eq) 11598a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel return false; 1160860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else 1161860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1162860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1163860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1164860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 11658a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel MachineBasicBlock::iterator I = CmpInstr; 1166860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1167860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Scan forward to find the first use of the compare. 1168860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (MachineBasicBlock::iterator EL = CmpInstr->getParent()->end(); 1169860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel I != EL; ++I) { 1170860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool FoundUse = false; 1171860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (MachineRegisterInfo::use_iterator J = MRI->use_begin(CRReg), 1172860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel JE = MRI->use_end(); J != JE; ++J) 1173860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (&*J == &*I) { 1174860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel FoundUse = true; 1175860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel break; 1176860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1177860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1178860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (FoundUse) 1179860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel break; 1180860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1181860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1182860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // There are two possible candidates which can be changed to set CR[01]. 1183860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // One is MI, the other is a SUB instruction. 1184860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1). 1185860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineInstr *Sub = NULL; 1186860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (SrcReg2 != 0) 1187860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // MI is not a candidate for CMPrr. 1188860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MI = NULL; 1189860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // FIXME: Conservatively refuse to convert an instruction which isn't in the 1190860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // same BB as the comparison. This is to allow the check below to avoid calls 1191860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // (and other explicit clobbers); instead we should really check for these 1192860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // more explicitly (in at least a few predecessors). 1193860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel else if (MI->getParent() != CmpInstr->getParent() || Value != 0) { 1194860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // PPC does not have a record-form SUBri. 1195860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1196860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1197860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1198860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Search for Sub. 1199860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel const TargetRegisterInfo *TRI = &getRegisterInfo(); 1200860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel --I; 12018a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel 12028a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel // Get ready to iterate backward from CmpInstr. 12038a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel MachineBasicBlock::iterator E = MI, 12048a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel B = CmpInstr->getParent()->begin(); 12058a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel 1206860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (; I != E && !noSub; --I) { 1207860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel const MachineInstr &Instr = *I; 1208860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel unsigned IOpC = Instr.getOpcode(); 1209860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1210860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (&*I != CmpInstr && ( 1211b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel Instr.modifiesRegister(PPC::CR0, TRI) || 1212b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel Instr.readsRegister(PPC::CR0, TRI))) 1213860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // This instruction modifies or uses the record condition register after 1214860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // the one we want to change. While we could do this transformation, it 1215860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // would likely not be profitable. This transformation removes one 1216860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // instruction, and so even forcing RA to generate one move probably 1217860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // makes it unprofitable. 1218860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1219860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1220860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Check whether CmpInstr can be made redundant by the current instruction. 1221860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if ((OpC == PPC::CMPW || OpC == PPC::CMPLW || 1222860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel OpC == PPC::CMPD || OpC == PPC::CMPLD) && 1223860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) && 1224860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel ((Instr.getOperand(1).getReg() == SrcReg && 1225860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Instr.getOperand(2).getReg() == SrcReg2) || 1226860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel (Instr.getOperand(1).getReg() == SrcReg2 && 1227860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Instr.getOperand(2).getReg() == SrcReg))) { 1228860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Sub = &*I; 1229860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel break; 1230860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1231860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1232860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (I == B) 1233860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // The 'and' is below the comparison instruction. 1234860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1235860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1236860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1237860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Return false if no candidates exist. 1238860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (!MI && !Sub) 1239860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1240860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1241860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // The single candidate is called MI. 1242860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (!MI) MI = Sub; 1243860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1244860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel int NewOpC = -1; 1245860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MIOpC = MI->getOpcode(); 1246860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (MIOpC == PPC::ANDIo || MIOpC == PPC::ANDIo8) 1247860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel NewOpC = MIOpC; 1248860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel else { 1249860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel NewOpC = PPC::getRecordFormOpcode(MIOpC); 1250860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (NewOpC == -1 && PPC::getNonRecordFormOpcode(MIOpC) != -1) 1251860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel NewOpC = MIOpC; 1252860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1253860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1254860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // FIXME: On the non-embedded POWER architectures, only some of the record 1255860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // forms are fast, and we should use only the fast ones. 1256860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1257860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // The defining instruction has a record form (or is already a record 1258860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // form). It is possible, however, that we'll need to reverse the condition 1259860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // code of the users. 1260860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (NewOpC == -1) 1261860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1262860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 126387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel SmallVector<std::pair<MachineOperand*, PPC::Predicate>, 4> PredsToUpdate; 126487c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel SmallVector<std::pair<MachineOperand*, unsigned>, 4> SubRegsToUpdate; 1265860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1266860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP 1267860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // needs to be updated to be based on SUB. Push the condition code 1268860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // operands to OperandsToUpdate. If it is safe to remove CmpInstr, the 1269860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // condition code of these operands will be modified. 1270860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel bool ShouldSwap = false; 1271860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (Sub) { 1272860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 && 1273860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel Sub->getOperand(2).getReg() == SrcReg; 1274860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1275860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // The operands to subf are the opposite of sub, so only in the fixed-point 1276860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // case, invert the order. 1277b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel ShouldSwap = !ShouldSwap; 1278860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1279860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1280860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (ShouldSwap) 1281860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (MachineRegisterInfo::use_iterator I = MRI->use_begin(CRReg), 1282860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel IE = MRI->use_end(); I != IE; ++I) { 1283860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineInstr *UseMI = &*I; 1284860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (UseMI->getOpcode() == PPC::BCC) { 1285860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm(); 128687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel assert((!equalityOnly || 128787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel Pred == PPC::PRED_EQ || Pred == PPC::PRED_NE) && 128887c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel "Invalid predicate for equality-only optimization"); 128987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel PredsToUpdate.push_back(std::make_pair(&((*I).getOperand(0)), 1290abe64dc6f7363c7e6170568e382fb06d81d62f51Hal Finkel PPC::getSwappedPredicate(Pred))); 1291860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else if (UseMI->getOpcode() == PPC::ISEL || 1292860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel UseMI->getOpcode() == PPC::ISEL8) { 129387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel unsigned NewSubReg = UseMI->getOperand(3).getSubReg(); 129487c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel assert((!equalityOnly || NewSubReg == PPC::sub_eq) && 129587c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel "Invalid CR bit for equality-only optimization"); 129687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel 129787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel if (NewSubReg == PPC::sub_lt) 129887c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel NewSubReg = PPC::sub_gt; 129987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel else if (NewSubReg == PPC::sub_gt) 130087c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel NewSubReg = PPC::sub_lt; 130187c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel 130287c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel SubRegsToUpdate.push_back(std::make_pair(&((*I).getOperand(3)), 130387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel NewSubReg)); 1304860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } else // We need to abort on a user we don't understand. 1305860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return false; 1306860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1307860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1308860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Create a new virtual register to hold the value of the CR set by the 1309860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // record-form instruction. If the instruction was not previously in 1310860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // record form, then set the kill flag on the CR. 1311860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel CmpInstr->eraseFromParent(); 1312860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1313860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineBasicBlock::iterator MII = MI; 1314860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel BuildMI(*MI->getParent(), llvm::next(MII), MI->getDebugLoc(), 1315860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel get(TargetOpcode::COPY), CRReg) 1316b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0); 1317860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1318860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (MIOpC != NewOpC) { 1319860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // We need to be careful here: we're replacing one instruction with 1320860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // another, and we need to make sure that we get all of the right 1321860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // implicit uses and defs. On the other hand, the caller may be holding 1322860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // an iterator to this instruction, and so we can't delete it (this is 1323860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // specifically the case if this is the instruction directly after the 1324860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // compare). 1325860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1326860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel const MCInstrDesc &NewDesc = get(NewOpC); 1327860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MI->setDesc(NewDesc); 1328860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1329860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (NewDesc.ImplicitDefs) 1330860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (const uint16_t *ImpDefs = NewDesc.getImplicitDefs(); 1331860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel *ImpDefs; ++ImpDefs) 1332860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (!MI->definesRegister(*ImpDefs)) 1333860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MI->addOperand(*MI->getParent()->getParent(), 1334860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineOperand::CreateReg(*ImpDefs, true, true)); 1335860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (NewDesc.ImplicitUses) 1336860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel for (const uint16_t *ImpUses = NewDesc.getImplicitUses(); 1337860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel *ImpUses; ++ImpUses) 1338860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel if (!MI->readsRegister(*ImpUses)) 1339860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MI->addOperand(*MI->getParent()->getParent(), 1340860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel MachineOperand::CreateReg(*ImpUses, false, true)); 1341860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel } 1342860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1343860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Modify the condition code of operands in OperandsToUpdate. 1344860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to 1345860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc. 134687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++) 134787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel PredsToUpdate[i].first->setImm(PredsToUpdate[i].second); 1348860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 134987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++) 135087c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second); 1351860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 1352860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel return true; 1353860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel} 1354860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel 135552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray/// GetInstSize - Return the number of bytes of code the specified 135652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray/// instruction may be. This returns the maximum number of bytes. 135752e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray/// 135852e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffrayunsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 135952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray switch (MI->getOpcode()) { 136052e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray case PPC::INLINEASM: { // Inline Asm: Variable size. 136152e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray const MachineFunction *MF = MI->getParent()->getParent(); 136252e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray const char *AsmStr = MI->getOperand(0).getSymbolName(); 1363af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 136452e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray } 13657431beaba2a01c3fe299c861b2ec85cbf1dc81c4Bill Wendling case PPC::PROLOG_LABEL: 13664406604047423576e36657c7ede266ca42e79642Dan Gohman case PPC::EH_LABEL: 13674406604047423576e36657c7ede266ca42e79642Dan Gohman case PPC::GC_LABEL: 1368375be7730a6f3dee7a6dc319ee6c355a11ac99adDale Johannesen case PPC::DBG_VALUE: 136952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray return 0; 137086765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand case PPC::BL8_NOP: 137186765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand case PPC::BLA8_NOP: 13725b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel return 8; 137352e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray default: 137452e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray return 4; // PowerPC instructions are all 4 bytes 137552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray } 137652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray} 13775ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 13785ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#undef DEBUG_TYPE 13795ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#define DEBUG_TYPE "ppc-early-ret" 13805ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelSTATISTIC(NumBCLR, "Number of early conditional returns"); 13815ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelSTATISTIC(NumBLR, "Number of early returns"); 13825ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 13835ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelnamespace llvm { 13845ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel void initializePPCEarlyReturnPass(PassRegistry&); 13855ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel} 13865ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 13875ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelnamespace { 13885ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // PPCEarlyReturn pass - For simple functions without epilogue code, move 13895ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // returns up, and create conditional returns, to avoid unnecessary 13905ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // branch-to-blr sequences. 13915ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel struct PPCEarlyReturn : public MachineFunctionPass { 13925ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel static char ID; 13935ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel PPCEarlyReturn() : MachineFunctionPass(ID) { 13945ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel initializePPCEarlyReturnPass(*PassRegistry::getPassRegistry()); 13955ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 13965ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 13975ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel const PPCTargetMachine *TM; 13985ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel const PPCInstrInfo *TII; 13995ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14005ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelprotected: 140113049aef8ad86795e94006dea0e097a8add85665Hal Finkel bool processBlock(MachineBasicBlock &ReturnMBB) { 14025ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel bool Changed = false; 14035ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 140413049aef8ad86795e94006dea0e097a8add85665Hal Finkel MachineBasicBlock::iterator I = ReturnMBB.begin(); 140513049aef8ad86795e94006dea0e097a8add85665Hal Finkel I = ReturnMBB.SkipPHIsAndLabels(I); 14065ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14075ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // The block must be essentially empty except for the blr. 140813049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (I == ReturnMBB.end() || I->getOpcode() != PPC::BLR || 140913049aef8ad86795e94006dea0e097a8add85665Hal Finkel I != ReturnMBB.getLastNonDebugInstr()) 14105ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel return Changed; 14115ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14125ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel SmallVector<MachineBasicBlock*, 8> PredToRemove; 141313049aef8ad86795e94006dea0e097a8add85665Hal Finkel for (MachineBasicBlock::pred_iterator PI = ReturnMBB.pred_begin(), 141413049aef8ad86795e94006dea0e097a8add85665Hal Finkel PIE = ReturnMBB.pred_end(); PI != PIE; ++PI) { 14155ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel bool OtherReference = false, BlockChanged = false; 141613049aef8ad86795e94006dea0e097a8add85665Hal Finkel for (MachineBasicBlock::iterator J = (*PI)->getLastNonDebugInstr();;) { 14175ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (J->getOpcode() == PPC::B) { 141813049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (J->getOperand(0).getMBB() == &ReturnMBB) { 14195ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // This is an unconditional branch to the return. Replace the 14205ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // branch with a blr. 14215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BLR)); 142213049aef8ad86795e94006dea0e097a8add85665Hal Finkel MachineBasicBlock::iterator K = J--; 14235ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel K->eraseFromParent(); 14245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel BlockChanged = true; 14255ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel ++NumBLR; 14265ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel continue; 14275ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14285ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } else if (J->getOpcode() == PPC::BCC) { 142913049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (J->getOperand(2).getMBB() == &ReturnMBB) { 14305ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // This is a conditional branch to the return. Replace the branch 14315ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // with a bclr. 14325ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BCLR)) 14335ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel .addImm(J->getOperand(0).getImm()) 14345ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel .addReg(J->getOperand(1).getReg()); 143513049aef8ad86795e94006dea0e097a8add85665Hal Finkel MachineBasicBlock::iterator K = J--; 14365ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel K->eraseFromParent(); 14375ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel BlockChanged = true; 14385ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel ++NumBCLR; 14395ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel continue; 14405ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14415ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } else if (J->isBranch()) { 14425ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (J->isIndirectBranch()) { 144313049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (ReturnMBB.hasAddressTaken()) 14445ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel OtherReference = true; 14455ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } else 14465ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel for (unsigned i = 0; i < J->getNumOperands(); ++i) 14475ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (J->getOperand(i).isMBB() && 144813049aef8ad86795e94006dea0e097a8add85665Hal Finkel J->getOperand(i).getMBB() == &ReturnMBB) 14495ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel OtherReference = true; 145013049aef8ad86795e94006dea0e097a8add85665Hal Finkel } else if (!J->isTerminator() && !J->isDebugValue()) 145113049aef8ad86795e94006dea0e097a8add85665Hal Finkel break; 14525ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 145313049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (J == (*PI)->begin()) 145413049aef8ad86795e94006dea0e097a8add85665Hal Finkel break; 145513049aef8ad86795e94006dea0e097a8add85665Hal Finkel 145613049aef8ad86795e94006dea0e097a8add85665Hal Finkel --J; 14575ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14585ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 145913049aef8ad86795e94006dea0e097a8add85665Hal Finkel if ((*PI)->canFallThrough() && (*PI)->isLayoutSuccessor(&ReturnMBB)) 14605ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel OtherReference = true; 14615ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14625ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // Predecessors are stored in a vector and can't be removed here. 14635ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (!OtherReference && BlockChanged) { 14645ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel PredToRemove.push_back(*PI); 14655ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14665ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14675ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (BlockChanged) 14685ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel Changed = true; 14695ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14705ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14715ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i) 147213049aef8ad86795e94006dea0e097a8add85665Hal Finkel PredToRemove[i]->removeSuccessor(&ReturnMBB); 14735ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 147413049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (Changed && !ReturnMBB.hasAddressTaken()) { 14755ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // We now might be able to merge this blr-only block into its 14765ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // by-layout predecessor. 147713049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (ReturnMBB.pred_size() == 1 && 147813049aef8ad86795e94006dea0e097a8add85665Hal Finkel (*ReturnMBB.pred_begin())->isLayoutSuccessor(&ReturnMBB)) { 14795ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // Move the blr into the preceding block. 148013049aef8ad86795e94006dea0e097a8add85665Hal Finkel MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin(); 148113049aef8ad86795e94006dea0e097a8add85665Hal Finkel PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I); 148213049aef8ad86795e94006dea0e097a8add85665Hal Finkel PrevMBB.removeSuccessor(&ReturnMBB); 14835ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14845ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 148513049aef8ad86795e94006dea0e097a8add85665Hal Finkel if (ReturnMBB.pred_empty()) 148613049aef8ad86795e94006dea0e097a8add85665Hal Finkel ReturnMBB.eraseFromParent(); 14875ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14885ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14895ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel return Changed; 14905ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 14915ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14925ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelpublic: 14935ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel virtual bool runOnMachineFunction(MachineFunction &MF) { 14945ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel TM = static_cast<const PPCTargetMachine *>(&MF.getTarget()); 14955ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel TII = TM->getInstrInfo(); 14965ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 14975ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel bool Changed = false; 14985ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 149913049aef8ad86795e94006dea0e097a8add85665Hal Finkel // If the function does not have at least two blocks, then there is 15005ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel // nothing to do. 15015ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (MF.size() < 2) 15025ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel return Changed; 15035ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 15045ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel for (MachineFunction::iterator I = MF.begin(); I != MF.end();) { 15055ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel MachineBasicBlock &B = *I++; 15065ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel if (processBlock(B)) 15075ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel Changed = true; 15085ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 15095ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 15105ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel return Changed; 15115ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 15125ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 15135ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel virtual void getAnalysisUsage(AnalysisUsage &AU) const { 15145ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel MachineFunctionPass::getAnalysisUsage(AU); 15155ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel } 15165ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel }; 15175ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel} 15185ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 15195ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelINITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE, 15205ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel "PowerPC Early-Return Creation", false, false) 15215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 15225ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelchar PPCEarlyReturn::ID = 0; 15235ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelFunctionPass* 15245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelllvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); } 15255ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel 1526