| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1 | //===- CodeGenPrepare.cpp - Prepare a function for code generation --------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | // This pass munges the code in the input function to better prepare it for | 
| Gordon Henriksen | 829046b | 2008-05-08 17:46:35 +0000 | [diff] [blame] | 10 | // SelectionDAG-based code generation. This works around limitations in it's | 
|  | 11 | // basic-block-at-a-time approach. It should eventually be removed. | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/APInt.h" | 
|  | 16 | #include "llvm/ADT/ArrayRef.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/DenseMap.h" | 
| Eric Christopher | b6c190d | 2019-04-12 06:16:33 +0000 | [diff] [blame] | 18 | #include "llvm/ADT/MapVector.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/PointerIntPair.h" | 
|  | 20 | #include "llvm/ADT/STLExtras.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/SmallPtrSet.h" | 
|  | 22 | #include "llvm/ADT/SmallVector.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/Statistic.h" | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 24 | #include "llvm/Analysis/BlockFrequencyInfo.h" | 
|  | 25 | #include "llvm/Analysis/BranchProbabilityInfo.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 26 | #include "llvm/Analysis/ConstantFolding.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 27 | #include "llvm/Analysis/InstructionSimplify.h" | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 28 | #include "llvm/Analysis/LoopInfo.h" | 
| Zaara Syeda | 3a7578c | 2017-05-31 17:12:38 +0000 | [diff] [blame] | 29 | #include "llvm/Analysis/MemoryBuiltins.h" | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 30 | #include "llvm/Analysis/ProfileSummaryInfo.h" | 
| Chandler Carruth | 62d4215 | 2015-01-15 02:16:27 +0000 | [diff] [blame] | 31 | #include "llvm/Analysis/TargetLibraryInfo.h" | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 32 | #include "llvm/Analysis/TargetTransformInfo.h" | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 33 | #include "llvm/Analysis/ValueTracking.h" | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 34 | #include "llvm/Analysis/VectorUtils.h" | 
| Michael Kuperstein | f79af6f | 2016-09-08 00:48:37 +0000 | [diff] [blame] | 35 | #include "llvm/CodeGen/Analysis.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 36 | #include "llvm/CodeGen/ISDOpcodes.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 37 | #include "llvm/CodeGen/SelectionDAGNodes.h" | 
| David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 38 | #include "llvm/CodeGen/TargetLowering.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 39 | #include "llvm/CodeGen/TargetPassConfig.h" | 
| David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 40 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | 
| Craig Topper | 2fa1436 | 2018-03-29 17:21:10 +0000 | [diff] [blame] | 41 | #include "llvm/CodeGen/ValueTypes.h" | 
| Nico Weber | 432a388 | 2018-04-30 14:59:11 +0000 | [diff] [blame] | 42 | #include "llvm/Config/llvm-config.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 43 | #include "llvm/IR/Argument.h" | 
|  | 44 | #include "llvm/IR/Attributes.h" | 
|  | 45 | #include "llvm/IR/BasicBlock.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 46 | #include "llvm/IR/Constant.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 47 | #include "llvm/IR/Constants.h" | 
|  | 48 | #include "llvm/IR/DataLayout.h" | 
|  | 49 | #include "llvm/IR/DerivedTypes.h" | 
| Chandler Carruth | 5ad5f15 | 2014-01-13 09:26:24 +0000 | [diff] [blame] | 50 | #include "llvm/IR/Dominators.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 51 | #include "llvm/IR/Function.h" | 
| Chandler Carruth | 03eb0de | 2014-03-04 10:40:04 +0000 | [diff] [blame] | 52 | #include "llvm/IR/GetElementPtrTypeIterator.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 53 | #include "llvm/IR/GlobalValue.h" | 
|  | 54 | #include "llvm/IR/GlobalVariable.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 55 | #include "llvm/IR/IRBuilder.h" | 
|  | 56 | #include "llvm/IR/InlineAsm.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 57 | #include "llvm/IR/InstrTypes.h" | 
|  | 58 | #include "llvm/IR/Instruction.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 59 | #include "llvm/IR/Instructions.h" | 
|  | 60 | #include "llvm/IR/IntrinsicInst.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 61 | #include "llvm/IR/Intrinsics.h" | 
| Reid Kleckner | 5d98695 | 2019-12-11 07:55:26 -0800 | [diff] [blame] | 62 | #include "llvm/IR/IntrinsicsAArch64.h" | 
|  | 63 | #include "llvm/IR/IntrinsicsX86.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 64 | #include "llvm/IR/LLVMContext.h" | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 65 | #include "llvm/IR/MDBuilder.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 66 | #include "llvm/IR/Module.h" | 
|  | 67 | #include "llvm/IR/Operator.h" | 
| Chandler Carruth | 820a908 | 2014-03-04 11:08:18 +0000 | [diff] [blame] | 68 | #include "llvm/IR/PatternMatch.h" | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 69 | #include "llvm/IR/Statepoint.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 70 | #include "llvm/IR/Type.h" | 
|  | 71 | #include "llvm/IR/Use.h" | 
|  | 72 | #include "llvm/IR/User.h" | 
|  | 73 | #include "llvm/IR/Value.h" | 
| Chandler Carruth | 4220e9c | 2014-03-04 11:17:44 +0000 | [diff] [blame] | 74 | #include "llvm/IR/ValueHandle.h" | 
| Chandler Carruth | a4ea269 | 2014-03-04 11:26:31 +0000 | [diff] [blame] | 75 | #include "llvm/IR/ValueMap.h" | 
| Reid Kleckner | 05da2fe | 2019-11-13 13:15:01 -0800 | [diff] [blame] | 76 | #include "llvm/InitializePasses.h" | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 77 | #include "llvm/Pass.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 78 | #include "llvm/Support/BlockFrequency.h" | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 79 | #include "llvm/Support/BranchProbability.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 80 | #include "llvm/Support/Casting.h" | 
| Evan Cheng | 8b637b1 | 2010-08-17 01:34:49 +0000 | [diff] [blame] | 81 | #include "llvm/Support/CommandLine.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 82 | #include "llvm/Support/Compiler.h" | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 83 | #include "llvm/Support/Debug.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 84 | #include "llvm/Support/ErrorHandling.h" | 
| David Blaikie | 13e77db | 2018-03-23 23:58:25 +0000 | [diff] [blame] | 85 | #include "llvm/Support/MachineValueType.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 86 | #include "llvm/Support/MathExtras.h" | 
| Chandler Carruth | aafe091 | 2012-06-29 12:38:19 +0000 | [diff] [blame] | 87 | #include "llvm/Support/raw_ostream.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 88 | #include "llvm/Target/TargetMachine.h" | 
|  | 89 | #include "llvm/Target/TargetOptions.h" | 
| Chandler Carruth | aafe091 | 2012-06-29 12:38:19 +0000 | [diff] [blame] | 90 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 91 | #include "llvm/Transforms/Utils/BypassSlowDivision.h" | 
| Reid Kleckner | 05da2fe | 2019-11-13 13:15:01 -0800 | [diff] [blame] | 92 | #include "llvm/Transforms/Utils/Local.h" | 
| Ahmed Bougacha | e03bef7 | 2015-01-12 17:22:43 +0000 | [diff] [blame] | 93 | #include "llvm/Transforms/Utils/SimplifyLibCalls.h" | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 94 | #include "llvm/Transforms/Utils/SizeOpts.h" | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 95 | #include <algorithm> | 
|  | 96 | #include <cassert> | 
|  | 97 | #include <cstdint> | 
|  | 98 | #include <iterator> | 
|  | 99 | #include <limits> | 
|  | 100 | #include <memory> | 
|  | 101 | #include <utility> | 
|  | 102 | #include <vector> | 
| Zaara Syeda | 3a7578c | 2017-05-31 17:12:38 +0000 | [diff] [blame] | 103 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 104 | using namespace llvm; | 
| Chris Lattner | d616ef5 | 2008-11-25 04:42:10 +0000 | [diff] [blame] | 105 | using namespace llvm::PatternMatch; | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 106 |  | 
| Chandler Carruth | 1b9dde0 | 2014-04-22 02:02:50 +0000 | [diff] [blame] | 107 | #define DEBUG_TYPE "codegenprepare" | 
|  | 108 |  | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 109 | STATISTIC(NumBlocksElim, "Number of blocks eliminated"); | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 110 | STATISTIC(NumPHIsElim,   "Number of trivial PHIs eliminated"); | 
|  | 111 | STATISTIC(NumGEPsElim,   "Number of GEPs converted to casts"); | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 112 | STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " | 
|  | 113 | "sunken Cmps"); | 
|  | 114 | STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " | 
|  | 115 | "of sunken Casts"); | 
|  | 116 | STATISTIC(NumMemoryInsts, "Number of memory instructions whose address " | 
|  | 117 | "computations were sunk"); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 118 | STATISTIC(NumMemoryInstsPhiCreated, | 
|  | 119 | "Number of phis created when address " | 
|  | 120 | "computations were sunk to memory instructions"); | 
|  | 121 | STATISTIC(NumMemoryInstsSelectCreated, | 
|  | 122 | "Number of select created when address " | 
|  | 123 | "computations were sunk to memory instructions"); | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 124 | STATISTIC(NumExtsMoved,  "Number of [s|z]ext instructions combined with loads"); | 
|  | 125 | STATISTIC(NumExtUses,    "Number of uses of [s|z]ext instructions optimized"); | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 126 | STATISTIC(NumAndsAdded, | 
|  | 127 | "Number of and mask instructions added to form ext loads"); | 
|  | 128 | STATISTIC(NumAndUses, "Number of uses of and mask instructions optimized"); | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 129 | STATISTIC(NumRetsDup,    "Number of return instructions duplicated"); | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 130 | STATISTIC(NumDbgValueMoved, "Number of debug value instructions moved"); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 131 | STATISTIC(NumSelectsExpanded, "Number of selects turned into branches"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 132 | STATISTIC(NumStoreExtractExposed, "Number of store(extractelement) exposed"); | 
| Jakob Stoklund Olesen | eb12f49 | 2010-09-30 20:51:52 +0000 | [diff] [blame] | 133 |  | 
| Cameron Zwarich | 338d362 | 2011-03-11 21:52:04 +0000 | [diff] [blame] | 134 | static cl::opt<bool> DisableBranchOpts( | 
|  | 135 | "disable-cgp-branch-opts", cl::Hidden, cl::init(false), | 
|  | 136 | cl::desc("Disable branch optimizations in CodeGenPrepare")); | 
|  | 137 |  | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 138 | static cl::opt<bool> | 
|  | 139 | DisableGCOpts("disable-cgp-gc-opts", cl::Hidden, cl::init(false), | 
|  | 140 | cl::desc("Disable GC optimizations in CodeGenPrepare")); | 
|  | 141 |  | 
| Benjamin Kramer | 3d38c17 | 2012-05-06 14:25:16 +0000 | [diff] [blame] | 142 | static cl::opt<bool> DisableSelectToBranch( | 
|  | 143 | "disable-cgp-select2branch", cl::Hidden, cl::init(false), | 
|  | 144 | cl::desc("Disable select to branch conversion.")); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 145 |  | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 146 | static cl::opt<bool> AddrSinkUsingGEPs( | 
| Eli Friedman | 5fba1e5 | 2017-04-06 22:42:18 +0000 | [diff] [blame] | 147 | "addr-sink-using-gep", cl::Hidden, cl::init(true), | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 148 | cl::desc("Address sinking in CGP using GEPs.")); | 
|  | 149 |  | 
| Tim Northover | cea0abb | 2014-03-29 08:22:29 +0000 | [diff] [blame] | 150 | static cl::opt<bool> EnableAndCmpSinking( | 
|  | 151 | "enable-andcmp-sinking", cl::Hidden, cl::init(true), | 
|  | 152 | cl::desc("Enable sinkinig and/cmp into branches.")); | 
|  | 153 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 154 | static cl::opt<bool> DisableStoreExtract( | 
|  | 155 | "disable-cgp-store-extract", cl::Hidden, cl::init(false), | 
|  | 156 | cl::desc("Disable store(extract) optimizations in CodeGenPrepare")); | 
|  | 157 |  | 
|  | 158 | static cl::opt<bool> StressStoreExtract( | 
|  | 159 | "stress-cgp-store-extract", cl::Hidden, cl::init(false), | 
|  | 160 | cl::desc("Stress test store(extract) optimizations in CodeGenPrepare")); | 
|  | 161 |  | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 162 | static cl::opt<bool> DisableExtLdPromotion( | 
|  | 163 | "disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), | 
|  | 164 | cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " | 
|  | 165 | "CodeGenPrepare")); | 
|  | 166 |  | 
|  | 167 | static cl::opt<bool> StressExtLdPromotion( | 
|  | 168 | "stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false), | 
|  | 169 | cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " | 
|  | 170 | "optimization in CodeGenPrepare")); | 
|  | 171 |  | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 172 | static cl::opt<bool> DisablePreheaderProtect( | 
|  | 173 | "disable-preheader-prot", cl::Hidden, cl::init(false), | 
|  | 174 | cl::desc("Disable protection against removing loop preheaders")); | 
|  | 175 |  | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 176 | static cl::opt<bool> ProfileGuidedSectionPrefix( | 
| David Callahan | 5960d9b1 | 2017-06-14 20:35:33 +0000 | [diff] [blame] | 177 | "profile-guided-section-prefix", cl::Hidden, cl::init(true), cl::ZeroOrMore, | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 178 | cl::desc("Use profile info to add section prefix for hot/cold functions")); | 
|  | 179 |  | 
| Wei Mi | aa2ddfc | 2020-05-04 17:17:34 -0700 | [diff] [blame] | 180 | static cl::opt<bool> ProfileUnknownInSpecialSection( | 
|  | 181 | "profile-unknown-in-special-section", cl::Hidden, cl::init(false), | 
|  | 182 | cl::ZeroOrMore, | 
|  | 183 | cl::desc("In profiling mode like sampleFDO, if a function doesn't have " | 
|  | 184 | "profile, we cannot tell the function is cold for sure because " | 
|  | 185 | "it may be a function newly added without ever being sampled. " | 
|  | 186 | "With the flag enabled, compiler can put such profile unknown " | 
|  | 187 | "functions into a special section, so runtime system can choose " | 
|  | 188 | "to handle it in a different way than .text section, to save " | 
|  | 189 | "RAM for example. ")); | 
|  | 190 |  | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 191 | static cl::opt<unsigned> FreqRatioToSkipMerge( | 
|  | 192 | "cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), | 
|  | 193 | cl::desc("Skip merging empty blocks if (frequency of empty block) / " | 
|  | 194 | "(frequency of destination block) is greater than this ratio")); | 
|  | 195 |  | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 196 | static cl::opt<bool> ForceSplitStore( | 
|  | 197 | "force-split-store", cl::Hidden, cl::init(false), | 
|  | 198 | cl::desc("Force store splitting no matter what the target query says.")); | 
|  | 199 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 200 | static cl::opt<bool> | 
|  | 201 | EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden, | 
|  | 202 | cl::desc("Enable merging of redundant sexts when one is dominating" | 
|  | 203 | " the other."), cl::init(true)); | 
|  | 204 |  | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 205 | static cl::opt<bool> DisableComplexAddrModes( | 
| Serguei Katkov | d4df744 | 2017-11-29 09:48:50 +0000 | [diff] [blame] | 206 | "disable-complex-addr-modes", cl::Hidden, cl::init(false), | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 207 | cl::desc("Disables combining addressing modes with different parts " | 
|  | 208 | "in optimizeMemoryInst.")); | 
|  | 209 |  | 
|  | 210 | static cl::opt<bool> | 
|  | 211 | AddrSinkNewPhis("addr-sink-new-phis", cl::Hidden, cl::init(false), | 
|  | 212 | cl::desc("Allow creation of Phis in Address sinking.")); | 
|  | 213 |  | 
|  | 214 | static cl::opt<bool> | 
| Serguei Katkov | 9fe0524 | 2018-01-26 06:26:56 +0000 | [diff] [blame] | 215 | AddrSinkNewSelects("addr-sink-new-select", cl::Hidden, cl::init(true), | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 216 | cl::desc("Allow creation of selects in Address sinking.")); | 
|  | 217 |  | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 218 | static cl::opt<bool> AddrSinkCombineBaseReg( | 
|  | 219 | "addr-sink-combine-base-reg", cl::Hidden, cl::init(true), | 
|  | 220 | cl::desc("Allow combining of BaseReg field in Address sinking.")); | 
|  | 221 |  | 
|  | 222 | static cl::opt<bool> AddrSinkCombineBaseGV( | 
|  | 223 | "addr-sink-combine-base-gv", cl::Hidden, cl::init(true), | 
|  | 224 | cl::desc("Allow combining of BaseGV field in Address sinking.")); | 
|  | 225 |  | 
|  | 226 | static cl::opt<bool> AddrSinkCombineBaseOffs( | 
|  | 227 | "addr-sink-combine-base-offs", cl::Hidden, cl::init(true), | 
|  | 228 | cl::desc("Allow combining of BaseOffs field in Address sinking.")); | 
|  | 229 |  | 
|  | 230 | static cl::opt<bool> AddrSinkCombineScaledReg( | 
|  | 231 | "addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), | 
|  | 232 | cl::desc("Allow combining of ScaledReg field in Address sinking.")); | 
|  | 233 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 234 | static cl::opt<bool> | 
|  | 235 | EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, | 
|  | 236 | cl::init(true), | 
|  | 237 | cl::desc("Enable splitting large offset of GEP.")); | 
|  | 238 |  | 
| Yi-Hong Lyu | 6bbfafd | 2019-11-11 16:15:52 +0000 | [diff] [blame] | 239 | static cl::opt<bool> EnableICMP_EQToICMP_ST( | 
|  | 240 | "cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), | 
|  | 241 | cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion.")); | 
|  | 242 |  | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 243 | static cl::opt<bool> | 
|  | 244 | VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), | 
|  | 245 | cl::desc("Enable BFI update verification for " | 
|  | 246 | "CodeGenPrepare.")); | 
|  | 247 |  | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 248 | namespace { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 249 |  | 
| Guozhi Wei | 8c17f9a | 2018-08-15 22:08:26 +0000 | [diff] [blame] | 250 | enum ExtType { | 
|  | 251 | ZeroExtension,   // Zero extension has been seen. | 
|  | 252 | SignExtension,   // Sign extension has been seen. | 
|  | 253 | BothExtension    // This extension type is used if we saw sext after | 
|  | 254 | // ZeroExtension had been set, or if we saw zext after | 
|  | 255 | // SignExtension had been set. It makes the type | 
|  | 256 | // information of a promoted instruction invalid. | 
|  | 257 | }; | 
|  | 258 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 259 | using SetOfInstrs = SmallPtrSet<Instruction *, 16>; | 
| Guozhi Wei | 8c17f9a | 2018-08-15 22:08:26 +0000 | [diff] [blame] | 260 | using TypeIsSExt = PointerIntPair<Type *, 2, ExtType>; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 261 | using InstrToOrigTy = DenseMap<Instruction *, TypeIsSExt>; | 
|  | 262 | using SExts = SmallVector<Instruction *, 16>; | 
|  | 263 | using ValueToSExts = DenseMap<Value *, SExts>; | 
|  | 264 |  | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 265 | class TypePromotionTransaction; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 266 |  | 
| Chris Lattner | 2dd09db | 2009-09-02 06:11:42 +0000 | [diff] [blame] | 267 | class CodeGenPrepare : public FunctionPass { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 268 | const TargetMachine *TM = nullptr; | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 269 | const TargetSubtargetInfo *SubtargetInfo; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 270 | const TargetLowering *TLI = nullptr; | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 271 | const TargetRegisterInfo *TRI; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 272 | const TargetTransformInfo *TTI = nullptr; | 
| Chad Rosier | c24b86f | 2011-12-01 03:08:23 +0000 | [diff] [blame] | 273 | const TargetLibraryInfo *TLInfo; | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 274 | const LoopInfo *LI; | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 275 | std::unique_ptr<BlockFrequencyInfo> BFI; | 
|  | 276 | std::unique_ptr<BranchProbabilityInfo> BPI; | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 277 | ProfileSummaryInfo *PSI; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 278 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 279 | /// As we scan instructions optimizing them, this is the next instruction | 
|  | 280 | /// to optimize. Transforms that can invalidate this should update it. | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 281 | BasicBlock::iterator CurInstIterator; | 
| Evan Cheng | 3b3de7c | 2008-12-19 18:03:11 +0000 | [diff] [blame] | 282 |  | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 283 | /// Keeps track of non-local addresses that have been sunk into a block. | 
|  | 284 | /// This allows us to avoid inserting duplicate code for blocks with | 
| Simon Dardis | 230f453 | 2017-11-24 16:45:28 +0000 | [diff] [blame] | 285 | /// multiple load/stores of the same address. The usage of WeakTrackingVH | 
|  | 286 | /// enables SunkAddrs to be treated as a cache whose entries can be | 
|  | 287 | /// invalidated if a sunken address computation has been erased. | 
|  | 288 | ValueMap<Value*, WeakTrackingVH> SunkAddrs; | 
| Cameron Zwarich | ce3b930 | 2011-01-06 00:42:50 +0000 | [diff] [blame] | 289 |  | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 290 | /// Keeps track of all instructions inserted for the current function. | 
|  | 291 | SetOfInstrs InsertedInsts; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 292 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 293 | /// Keeps track of the type of the related instruction before their | 
|  | 294 | /// promotion for the current function. | 
|  | 295 | InstrToOrigTy PromotedInsts; | 
|  | 296 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 297 | /// Keep track of instructions removed during promotion. | 
|  | 298 | SetOfInstrs RemovedInsts; | 
|  | 299 |  | 
|  | 300 | /// Keep track of sext chains based on their initial value. | 
|  | 301 | DenseMap<Value *, Instruction *> SeenChainsForSExt; | 
|  | 302 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 303 | /// Keep track of GEPs accessing the same data structures such as structs or | 
|  | 304 | /// arrays that are candidates to be split later because of their large | 
|  | 305 | /// size. | 
| David Green | e27e87c | 2018-09-12 10:19:10 +0000 | [diff] [blame] | 306 | MapVector< | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 307 | AssertingVH<Value>, | 
|  | 308 | SmallVector<std::pair<AssertingVH<GetElementPtrInst>, int64_t>, 32>> | 
|  | 309 | LargeOffsetGEPMap; | 
|  | 310 |  | 
|  | 311 | /// Keep track of new GEP base after splitting the GEPs having large offset. | 
|  | 312 | SmallSet<AssertingVH<Value>, 2> NewGEPBases; | 
|  | 313 |  | 
|  | 314 | /// Map serial numbers to Large offset GEPs. | 
|  | 315 | DenseMap<AssertingVH<GetElementPtrInst>, int> LargeOffsetGEPID; | 
|  | 316 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 317 | /// Keep track of SExt promoted. | 
|  | 318 | ValueToSExts ValToSExtendedUses; | 
|  | 319 |  | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 320 | /// True if the function has the OptSize attribute. | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 321 | bool OptSize; | 
|  | 322 |  | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 323 | /// DataLayout for the Function being processed. | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 324 | const DataLayout *DL = nullptr; | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 325 |  | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 326 | /// Building the dominator tree can be expensive, so we only build it | 
|  | 327 | /// lazily and update it when required. | 
|  | 328 | std::unique_ptr<DominatorTree> DT; | 
|  | 329 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 330 | public: | 
| Nick Lewycky | e7da2d6 | 2007-05-06 13:37:16 +0000 | [diff] [blame] | 331 | static char ID; // Pass identification, replacement for typeid | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 332 |  | 
|  | 333 | CodeGenPrepare() : FunctionPass(ID) { | 
| Francis Visoiu Mistrih | 8b61764 | 2017-05-18 17:21:13 +0000 | [diff] [blame] | 334 | initializeCodeGenPreparePass(*PassRegistry::getPassRegistry()); | 
|  | 335 | } | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 336 |  | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 337 | bool runOnFunction(Function &F) override; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 338 |  | 
| Mehdi Amini | 117296c | 2016-10-01 02:56:57 +0000 | [diff] [blame] | 339 | StringRef getPassName() const override { return "CodeGen Prepare"; } | 
| Evan Cheng | 99cafb1 | 2012-12-21 01:48:14 +0000 | [diff] [blame] | 340 |  | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 341 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
| George Burgess IV | d4febd1 | 2016-03-22 21:25:08 +0000 | [diff] [blame] | 342 | // FIXME: When we can selectively preserve passes, preserve the domtree. | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 343 | AU.addRequired<ProfileSummaryInfoWrapperPass>(); | 
| Chandler Carruth | b98f63d | 2015-01-15 10:41:28 +0000 | [diff] [blame] | 344 | AU.addRequired<TargetLibraryInfoWrapperPass>(); | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 345 | AU.addRequired<TargetPassConfig>(); | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 346 | AU.addRequired<TargetTransformInfoWrapperPass>(); | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 347 | AU.addRequired<LoopInfoWrapperPass>(); | 
| Andreas Neustifter | f8cb758 | 2009-09-16 09:26:52 +0000 | [diff] [blame] | 348 | } | 
|  | 349 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 350 | private: | 
| James Y Knight | 72f76bf | 2018-11-07 15:24:12 +0000 | [diff] [blame] | 351 | template <typename F> | 
|  | 352 | void resetIteratorIfInvalidatedWhileCalling(BasicBlock *BB, F f) { | 
|  | 353 | // Substituting can cause recursive simplifications, which can invalidate | 
|  | 354 | // our iterator.  Use a WeakTrackingVH to hold onto it in case this | 
|  | 355 | // happens. | 
|  | 356 | Value *CurValue = &*CurInstIterator; | 
|  | 357 | WeakTrackingVH IterHandle(CurValue); | 
|  | 358 |  | 
|  | 359 | f(); | 
|  | 360 |  | 
|  | 361 | // If the iterator instruction was recursively deleted, start over at the | 
|  | 362 | // start of the block. | 
|  | 363 | if (IterHandle != CurValue) { | 
|  | 364 | CurInstIterator = BB->begin(); | 
|  | 365 | SunkAddrs.clear(); | 
|  | 366 | } | 
|  | 367 | } | 
|  | 368 |  | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 369 | // Get the DominatorTree, building if necessary. | 
|  | 370 | DominatorTree &getDT(Function &F) { | 
|  | 371 | if (!DT) | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 372 | DT = std::make_unique<DominatorTree>(F); | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 373 | return *DT; | 
|  | 374 | } | 
|  | 375 |  | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 376 | bool eliminateFallThrough(Function &F); | 
|  | 377 | bool eliminateMostlyEmptyBlocks(Function &F); | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 378 | BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 379 | bool canMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const; | 
|  | 380 | void eliminateMostlyEmptyBlock(BasicBlock *BB); | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 381 | bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB, | 
|  | 382 | bool isPreheader); | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 383 | bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT); | 
|  | 384 | bool optimizeInst(Instruction *I, bool &ModifiedDT); | 
| Fangrui Song | cb0bab8 | 2018-07-16 18:51:40 +0000 | [diff] [blame] | 385 | bool optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, | 
|  | 386 | Type *AccessTy, unsigned AddrSpace); | 
| Craig Topper | 944cc5e | 2020-04-16 17:03:16 -0700 | [diff] [blame] | 387 | bool optimizeGatherScatterInst(Instruction *MemoryInst, Value *Ptr); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 388 | bool optimizeInlineAsmInst(CallInst *CS); | 
| Sanjay Patel | 3b8974b | 2017-06-08 20:00:09 +0000 | [diff] [blame] | 389 | bool optimizeCallInst(CallInst *CI, bool &ModifiedDT); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 390 | bool optimizeExt(Instruction *&I); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 391 | bool optimizeExtUses(Instruction *I); | 
| Fangrui Song | cb0bab8 | 2018-07-16 18:51:40 +0000 | [diff] [blame] | 392 | bool optimizeLoadExt(LoadInst *Load); | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 393 | bool optimizeShiftInst(BinaryOperator *BO); | 
| Sanjay Patel | 5be37cb | 2020-05-15 15:22:30 -0400 | [diff] [blame] | 394 | bool optimizeFunnelShift(IntrinsicInst *Fsh); | 
| Teresa Johnson | b7e2138 | 2019-03-27 18:44:25 +0000 | [diff] [blame] | 395 | bool optimizeSelectInst(SelectInst *SI); | 
| Fangrui Song | cb0bab8 | 2018-07-16 18:51:40 +0000 | [diff] [blame] | 396 | bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI); | 
|  | 397 | bool optimizeSwitchInst(SwitchInst *SI); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 398 | bool optimizeExtractElementInst(Instruction *Inst); | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 399 | bool dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT); | 
| Jeremy Morse | c93a9b1 | 2019-12-06 11:21:27 +0000 | [diff] [blame] | 400 | bool fixupDbgValue(Instruction *I); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 401 | bool placeDbgValues(Function &F); | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 402 | bool canFormExtLd(const SmallVectorImpl<Instruction *> &MovedExts, | 
|  | 403 | LoadInst *&LI, Instruction *&Inst, bool HasPromoted); | 
|  | 404 | bool tryToPromoteExts(TypePromotionTransaction &TPT, | 
|  | 405 | const SmallVectorImpl<Instruction *> &Exts, | 
|  | 406 | SmallVectorImpl<Instruction *> &ProfitablyMovedExts, | 
|  | 407 | unsigned CreatedInstsCost = 0); | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 408 | bool mergeSExts(Function &F); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 409 | bool splitLargeGEPOffsets(); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 410 | bool performAddressTypePromotion( | 
|  | 411 | Instruction *&Inst, | 
|  | 412 | bool AllowPromotionWithoutCommonHeader, | 
|  | 413 | bool HasPromoted, TypePromotionTransaction &TPT, | 
|  | 414 | SmallVectorImpl<Instruction *> &SpeculativelyMovedExts); | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 415 | bool splitBranchCondition(Function &F, bool &ModifiedDT); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 416 | bool simplifyOffsetableRelocate(Instruction &I); | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 417 |  | 
|  | 418 | bool tryToSinkFreeOperands(Instruction *I); | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 419 | bool replaceMathCmpWithIntrinsic(BinaryOperator *BO, Value *Arg0, | 
|  | 420 | Value *Arg1, CmpInst *Cmp, | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 421 | Intrinsic::ID IID); | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 422 | bool optimizeCmp(CmpInst *Cmp, bool &ModifiedDT); | 
|  | 423 | bool combineToUSubWithOverflow(CmpInst *Cmp, bool &ModifiedDT); | 
|  | 424 | bool combineToUAddWithOverflow(CmpInst *Cmp, bool &ModifiedDT); | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 425 | void verifyBFIUpdates(Function &F); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 426 | }; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 427 |  | 
|  | 428 | } // end anonymous namespace | 
| Devang Patel | 09f162c | 2007-05-01 21:15:47 +0000 | [diff] [blame] | 429 |  | 
| Devang Patel | 8c78a0b | 2007-05-03 01:11:54 +0000 | [diff] [blame] | 430 | char CodeGenPrepare::ID = 0; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 431 |  | 
| Matthias Braun | 1527baa | 2017-05-25 21:26:32 +0000 | [diff] [blame] | 432 | INITIALIZE_PASS_BEGIN(CodeGenPrepare, DEBUG_TYPE, | 
| Francis Visoiu Mistrih | 8b61764 | 2017-05-18 17:21:13 +0000 | [diff] [blame] | 433 | "Optimize for code generation", false, false) | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 434 | INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) | 
| Matthias Braun | 1527baa | 2017-05-25 21:26:32 +0000 | [diff] [blame] | 435 | INITIALIZE_PASS_END(CodeGenPrepare, DEBUG_TYPE, | 
| Francis Visoiu Mistrih | 8b61764 | 2017-05-18 17:21:13 +0000 | [diff] [blame] | 436 | "Optimize for code generation", false, false) | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 437 |  | 
| Francis Visoiu Mistrih | 8b61764 | 2017-05-18 17:21:13 +0000 | [diff] [blame] | 438 | FunctionPass *llvm::createCodeGenPreparePass() { return new CodeGenPrepare(); } | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 439 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 440 | bool CodeGenPrepare::runOnFunction(Function &F) { | 
| Andrew Kaylor | aa641a5 | 2016-04-22 22:06:11 +0000 | [diff] [blame] | 441 | if (skipFunction(F)) | 
| Paul Robinson | 7c99ec5 | 2014-03-31 17:43:35 +0000 | [diff] [blame] | 442 | return false; | 
|  | 443 |  | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 444 | DL = &F.getParent()->getDataLayout(); | 
|  | 445 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 446 | bool EverMadeChange = false; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 447 | // Clear per function information. | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 448 | InsertedInsts.clear(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 449 | PromotedInsts.clear(); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 450 |  | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 451 | TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>(); | 
|  | 452 | SubtargetInfo = TM->getSubtargetImpl(F); | 
|  | 453 | TLI = SubtargetInfo->getTargetLowering(); | 
|  | 454 | TRI = SubtargetInfo->getRegisterInfo(); | 
| Teresa Johnson | 9c27b59 | 2019-09-07 03:09:36 +0000 | [diff] [blame] | 455 | TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); | 
| Chandler Carruth | fdb9c57 | 2015-02-01 12:01:35 +0000 | [diff] [blame] | 456 | TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 457 | LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); | 
| Teresa Johnson | a4ce3bf | 2017-12-20 17:53:10 +0000 | [diff] [blame] | 458 | BPI.reset(new BranchProbabilityInfo(F, *LI)); | 
|  | 459 | BFI.reset(new BlockFrequencyInfo(F, *BPI, *LI)); | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 460 | PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); | 
| Evandro Menezes | 85bd397 | 2019-04-04 22:40:06 +0000 | [diff] [blame] | 461 | OptSize = F.hasOptSize(); | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 462 | if (ProfileGuidedSectionPrefix) { | 
| Teresa Johnson | a4ce3bf | 2017-12-20 17:53:10 +0000 | [diff] [blame] | 463 | if (PSI->isFunctionHotInCallGraph(&F, *BFI)) | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 464 | F.setSectionPrefix(".hot"); | 
| Teresa Johnson | a4ce3bf | 2017-12-20 17:53:10 +0000 | [diff] [blame] | 465 | else if (PSI->isFunctionColdInCallGraph(&F, *BFI)) | 
| Teresa Johnson | 720d9b4 | 2017-05-09 01:43:24 +0000 | [diff] [blame] | 466 | F.setSectionPrefix(".unlikely"); | 
| Wei Mi | aa2ddfc | 2020-05-04 17:17:34 -0700 | [diff] [blame] | 467 | else if (ProfileUnknownInSpecialSection && PSI->hasPartialSampleProfile() && | 
|  | 468 | PSI->isFunctionHotnessUnknown(F)) | 
|  | 469 | F.setSectionPrefix(".unknown"); | 
| Dehao Chen | 302b69c | 2016-10-18 20:42:47 +0000 | [diff] [blame] | 470 | } | 
|  | 471 |  | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 472 | /// This optimization identifies DIV instructions that can be | 
|  | 473 | /// profitably bypassed and carried out with a shorter, faster divide. | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 474 | if (!OptSize && !PSI->hasHugeWorkingSetSize() && TLI->isSlowDivBypassed()) { | 
| Preston Gurd | 0d67f51 | 2012-10-04 21:33:40 +0000 | [diff] [blame] | 475 | const DenseMap<unsigned int, unsigned int> &BypassWidths = | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 476 | TLI->getBypassSlowDivWidths(); | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 477 | BasicBlock* BB = &*F.begin(); | 
|  | 478 | while (BB != nullptr) { | 
|  | 479 | // bypassSlowDivision may create new BBs, but we don't want to reapply the | 
|  | 480 | // optimization to those blocks. | 
|  | 481 | BasicBlock* Next = BB->getNextNode(); | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 482 | // F.hasOptSize is already checked in the outer if statement. | 
|  | 483 | if (!llvm::shouldOptimizeForSize(BB, PSI, BFI.get())) | 
|  | 484 | EverMadeChange |= bypassSlowDivision(BB, BypassWidths); | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 485 | BB = Next; | 
|  | 486 | } | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 487 | } | 
|  | 488 |  | 
|  | 489 | // Eliminate blocks that contain only PHI nodes and an | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 490 | // unconditional branch. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 491 | EverMadeChange |= eliminateMostlyEmptyBlocks(F); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 492 |  | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 493 | bool ModifiedDT = false; | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 494 | if (!DisableBranchOpts) | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 495 | EverMadeChange |= splitBranchCondition(F, ModifiedDT); | 
| Tim Northover | cea0abb | 2014-03-29 08:22:29 +0000 | [diff] [blame] | 496 |  | 
| Michael Kuperstein | 13bf8a2 | 2017-02-28 00:11:34 +0000 | [diff] [blame] | 497 | // Split some critical edges where one of the sources is an indirect branch, | 
|  | 498 | // to help generate sane code for PHIs involving such edges. | 
| Hiroshi Yamauchi | 9364fa3 | 2017-12-04 20:36:01 +0000 | [diff] [blame] | 499 | EverMadeChange |= SplitIndirectBrCriticalEdges(F); | 
| Michael Kuperstein | 13bf8a2 | 2017-02-28 00:11:34 +0000 | [diff] [blame] | 500 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 501 | bool MadeChange = true; | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 502 | while (MadeChange) { | 
|  | 503 | MadeChange = false; | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 504 | DT.reset(); | 
| Hans Wennborg | 02fbc71 | 2012-09-19 07:48:16 +0000 | [diff] [blame] | 505 | for (Function::iterator I = F.begin(); I != F.end(); ) { | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 506 | BasicBlock *BB = &*I++; | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 507 | bool ModifiedDTOnIteration = false; | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 508 | MadeChange |= optimizeBlock(*BB, ModifiedDTOnIteration); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 509 |  | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 510 | // Restart BB iteration if the dominator tree of the Function was changed | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 511 | if (ModifiedDTOnIteration) | 
|  | 512 | break; | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 513 | } | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 514 | if (EnableTypePromotionMerge && !ValToSExtendedUses.empty()) | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 515 | MadeChange |= mergeSExts(F); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 516 | if (!LargeOffsetGEPMap.empty()) | 
|  | 517 | MadeChange |= splitLargeGEPOffsets(); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 518 |  | 
| Guozhi Wei | 6d20937 | 2020-03-31 11:55:51 -0700 | [diff] [blame] | 519 | if (MadeChange) | 
|  | 520 | eliminateFallThrough(F); | 
|  | 521 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 522 | // Really free removed instructions during promotion. | 
|  | 523 | for (Instruction *I : RemovedInsts) | 
| Reid Kleckner | 96ab872 | 2017-05-18 17:24:10 +0000 | [diff] [blame] | 524 | I->deleteValue(); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 525 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 526 | EverMadeChange |= MadeChange; | 
| Peter Collingbourne | abd820a | 2018-10-23 21:23:18 +0000 | [diff] [blame] | 527 | SeenChainsForSExt.clear(); | 
|  | 528 | ValToSExtendedUses.clear(); | 
|  | 529 | RemovedInsts.clear(); | 
|  | 530 | LargeOffsetGEPMap.clear(); | 
|  | 531 | LargeOffsetGEPID.clear(); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 532 | } | 
| Cameron Zwarich | ce3b930 | 2011-01-06 00:42:50 +0000 | [diff] [blame] | 533 |  | 
|  | 534 | SunkAddrs.clear(); | 
|  | 535 |  | 
| Cameron Zwarich | 338d362 | 2011-03-11 21:52:04 +0000 | [diff] [blame] | 536 | if (!DisableBranchOpts) { | 
|  | 537 | MadeChange = false; | 
| David Stenberg | 23bba56 | 2018-07-02 14:23:48 +0000 | [diff] [blame] | 538 | // Use a set vector to get deterministic iteration order. The order the | 
|  | 539 | // blocks are removed may affect whether or not PHI nodes in successors | 
|  | 540 | // are removed. | 
|  | 541 | SmallSetVector<BasicBlock*, 8> WorkList; | 
| Duncan P. N. Exon Smith | 5914a97 | 2015-01-08 20:44:33 +0000 | [diff] [blame] | 542 | for (BasicBlock &BB : F) { | 
|  | 543 | SmallVector<BasicBlock *, 2> Successors(succ_begin(&BB), succ_end(&BB)); | 
|  | 544 | MadeChange |= ConstantFoldTerminator(&BB, true); | 
| Bill Wendling | 97b9359 | 2012-03-04 10:46:01 +0000 | [diff] [blame] | 545 | if (!MadeChange) continue; | 
|  | 546 |  | 
|  | 547 | for (SmallVectorImpl<BasicBlock*>::iterator | 
|  | 548 | II = Successors.begin(), IE = Successors.end(); II != IE; ++II) | 
|  | 549 | if (pred_begin(*II) == pred_end(*II)) | 
|  | 550 | WorkList.insert(*II); | 
|  | 551 | } | 
|  | 552 |  | 
| Bill Wendling | f3614fd | 2012-11-28 23:23:48 +0000 | [diff] [blame] | 553 | // Delete the dead blocks and any of their dead successors. | 
| Bill Wendling | ab417b6 | 2012-12-06 00:30:20 +0000 | [diff] [blame] | 554 | MadeChange |= !WorkList.empty(); | 
| Bill Wendling | f3614fd | 2012-11-28 23:23:48 +0000 | [diff] [blame] | 555 | while (!WorkList.empty()) { | 
| David Stenberg | 23bba56 | 2018-07-02 14:23:48 +0000 | [diff] [blame] | 556 | BasicBlock *BB = WorkList.pop_back_val(); | 
| Bill Wendling | f3614fd | 2012-11-28 23:23:48 +0000 | [diff] [blame] | 557 | SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB)); | 
|  | 558 |  | 
|  | 559 | DeleteDeadBlock(BB); | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 560 |  | 
| Bill Wendling | f3614fd | 2012-11-28 23:23:48 +0000 | [diff] [blame] | 561 | for (SmallVectorImpl<BasicBlock*>::iterator | 
|  | 562 | II = Successors.begin(), IE = Successors.end(); II != IE; ++II) | 
|  | 563 | if (pred_begin(*II) == pred_end(*II)) | 
|  | 564 | WorkList.insert(*II); | 
|  | 565 | } | 
| Cameron Zwarich | 338d362 | 2011-03-11 21:52:04 +0000 | [diff] [blame] | 566 |  | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 567 | // Merge pairs of basic blocks with unconditional branches, connected by | 
|  | 568 | // a single edge. | 
|  | 569 | if (EverMadeChange || MadeChange) | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 570 | MadeChange |= eliminateFallThrough(F); | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 571 |  | 
| Cameron Zwarich | 338d362 | 2011-03-11 21:52:04 +0000 | [diff] [blame] | 572 | EverMadeChange |= MadeChange; | 
|  | 573 | } | 
|  | 574 |  | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 575 | if (!DisableGCOpts) { | 
|  | 576 | SmallVector<Instruction *, 2> Statepoints; | 
|  | 577 | for (BasicBlock &BB : F) | 
|  | 578 | for (Instruction &I : BB) | 
|  | 579 | if (isStatepoint(I)) | 
|  | 580 | Statepoints.push_back(&I); | 
|  | 581 | for (auto &I : Statepoints) | 
|  | 582 | EverMadeChange |= simplifyOffsetableRelocate(*I); | 
|  | 583 | } | 
|  | 584 |  | 
| Vedant Kumar | 30406fd | 2018-08-21 23:43:08 +0000 | [diff] [blame] | 585 | // Do this last to clean up use-before-def scenarios introduced by other | 
|  | 586 | // preparatory transforms. | 
|  | 587 | EverMadeChange |= placeDbgValues(F); | 
|  | 588 |  | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 589 | #ifndef NDEBUG | 
|  | 590 | if (VerifyBFIUpdates) | 
|  | 591 | verifyBFIUpdates(F); | 
|  | 592 | #endif | 
|  | 593 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 594 | return EverMadeChange; | 
|  | 595 | } | 
|  | 596 |  | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 597 | // Verify BFI has been updated correctly by recomputing BFI and comparing them. | 
| Mehdi Amini | 8697d44 | 2020-05-17 23:16:21 +0000 | [diff] [blame] | 598 | void LLVM_ATTRIBUTE_UNUSED CodeGenPrepare::verifyBFIUpdates(Function &F) { | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 599 | DominatorTree NewDT(F); | 
|  | 600 | LoopInfo NewLI(NewDT); | 
|  | 601 | BranchProbabilityInfo NewBPI(F, NewLI, TLInfo); | 
|  | 602 | BlockFrequencyInfo NewBFI(F, NewBPI, NewLI); | 
|  | 603 | NewBFI.verifyMatch(*BFI); | 
|  | 604 | } | 
|  | 605 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 606 | /// Merge basic blocks which are connected by a single edge, where one of the | 
|  | 607 | /// basic blocks has a single successor pointing to the other basic block, | 
|  | 608 | /// which has a single predecessor. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 609 | bool CodeGenPrepare::eliminateFallThrough(Function &F) { | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 610 | bool Changed = false; | 
|  | 611 | // Scan all of the blocks in the function, except for the entry block. | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 612 | // Use a temporary array to avoid iterator being invalidated when | 
|  | 613 | // deleting blocks. | 
|  | 614 | SmallVector<WeakTrackingVH, 16> Blocks; | 
|  | 615 | for (auto &Block : llvm::make_range(std::next(F.begin()), F.end())) | 
|  | 616 | Blocks.push_back(&Block); | 
|  | 617 |  | 
|  | 618 | for (auto &Block : Blocks) { | 
|  | 619 | auto *BB = cast_or_null<BasicBlock>(Block); | 
|  | 620 | if (!BB) | 
|  | 621 | continue; | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 622 | // If the destination block has a single pred, then this is a trivial | 
|  | 623 | // edge, just collapse it. | 
|  | 624 | BasicBlock *SinglePred = BB->getSinglePredecessor(); | 
|  | 625 |  | 
| Evan Cheng | 64a223a | 2012-09-28 23:58:57 +0000 | [diff] [blame] | 626 | // Don't merge if BB's address is taken. | 
|  | 627 | if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue; | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 628 |  | 
|  | 629 | BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator()); | 
|  | 630 | if (Term && !Term->isConditional()) { | 
|  | 631 | Changed = true; | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 632 | LLVM_DEBUG(dbgs() << "To merge:\n" << *BB << "\n\n\n"); | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 633 |  | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 634 | // Merge BB into SinglePred and delete it. | 
|  | 635 | MergeBlockIntoPredecessor(BB); | 
| Nadav Rotem | 7040999 | 2012-08-14 05:19:07 +0000 | [diff] [blame] | 636 | } | 
|  | 637 | } | 
|  | 638 | return Changed; | 
|  | 639 | } | 
|  | 640 |  | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 641 | /// Find a destination block from BB if BB is mergeable empty block. | 
|  | 642 | BasicBlock *CodeGenPrepare::findDestBlockOfMergeableEmptyBlock(BasicBlock *BB) { | 
|  | 643 | // If this block doesn't end with an uncond branch, ignore it. | 
|  | 644 | BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()); | 
|  | 645 | if (!BI || !BI->isUnconditional()) | 
|  | 646 | return nullptr; | 
|  | 647 |  | 
|  | 648 | // If the instruction before the branch (skipping debug info) isn't a phi | 
|  | 649 | // node, then other stuff is happening here. | 
|  | 650 | BasicBlock::iterator BBI = BI->getIterator(); | 
|  | 651 | if (BBI != BB->begin()) { | 
|  | 652 | --BBI; | 
|  | 653 | while (isa<DbgInfoIntrinsic>(BBI)) { | 
|  | 654 | if (BBI == BB->begin()) | 
|  | 655 | break; | 
|  | 656 | --BBI; | 
|  | 657 | } | 
|  | 658 | if (!isa<DbgInfoIntrinsic>(BBI) && !isa<PHINode>(BBI)) | 
|  | 659 | return nullptr; | 
|  | 660 | } | 
|  | 661 |  | 
|  | 662 | // Do not break infinite loops. | 
|  | 663 | BasicBlock *DestBB = BI->getSuccessor(0); | 
|  | 664 | if (DestBB == BB) | 
|  | 665 | return nullptr; | 
|  | 666 |  | 
|  | 667 | if (!canMergeBlocks(BB, DestBB)) | 
|  | 668 | DestBB = nullptr; | 
|  | 669 |  | 
|  | 670 | return DestBB; | 
|  | 671 | } | 
|  | 672 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 673 | /// Eliminate blocks that contain only PHI nodes, debug info directives, and an | 
|  | 674 | /// unconditional branch. Passes before isel (e.g. LSR/loopsimplify) often split | 
|  | 675 | /// edges in ways that are non-optimal for isel. Start by eliminating these | 
|  | 676 | /// blocks so we can split them the way we want them. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 677 | bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F) { | 
| Chuang-Yu Cheng | d3fb38c | 2016-04-05 14:06:20 +0000 | [diff] [blame] | 678 | SmallPtrSet<BasicBlock *, 16> Preheaders; | 
|  | 679 | SmallVector<Loop *, 16> LoopList(LI->begin(), LI->end()); | 
|  | 680 | while (!LoopList.empty()) { | 
|  | 681 | Loop *L = LoopList.pop_back_val(); | 
|  | 682 | LoopList.insert(LoopList.end(), L->begin(), L->end()); | 
|  | 683 | if (BasicBlock *Preheader = L->getLoopPreheader()) | 
|  | 684 | Preheaders.insert(Preheader); | 
|  | 685 | } | 
|  | 686 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 687 | bool MadeChange = false; | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 688 | // Copy blocks into a temporary array to avoid iterator invalidation issues | 
|  | 689 | // as we remove them. | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 690 | // Note that this intentionally skips the entry block. | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 691 | SmallVector<WeakTrackingVH, 16> Blocks; | 
|  | 692 | for (auto &Block : llvm::make_range(std::next(F.begin()), F.end())) | 
|  | 693 | Blocks.push_back(&Block); | 
|  | 694 |  | 
|  | 695 | for (auto &Block : Blocks) { | 
|  | 696 | BasicBlock *BB = cast_or_null<BasicBlock>(Block); | 
|  | 697 | if (!BB) | 
|  | 698 | continue; | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 699 | BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB); | 
|  | 700 | if (!DestBB || | 
|  | 701 | !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.count(BB))) | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 702 | continue; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 703 |  | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 704 | eliminateMostlyEmptyBlock(BB); | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 705 | MadeChange = true; | 
|  | 706 | } | 
|  | 707 | return MadeChange; | 
|  | 708 | } | 
|  | 709 |  | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 710 | bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB, | 
|  | 711 | BasicBlock *DestBB, | 
|  | 712 | bool isPreheader) { | 
|  | 713 | // Do not delete loop preheaders if doing so would create a critical edge. | 
|  | 714 | // Loop preheaders can be good locations to spill registers. If the | 
|  | 715 | // preheader is deleted and we create a critical edge, registers may be | 
|  | 716 | // spilled in the loop body instead. | 
|  | 717 | if (!DisablePreheaderProtect && isPreheader && | 
|  | 718 | !(BB->getSinglePredecessor() && | 
|  | 719 | BB->getSinglePredecessor()->getSingleSuccessor())) | 
|  | 720 | return false; | 
|  | 721 |  | 
| Craig Topper | 784929d | 2019-02-08 20:48:56 +0000 | [diff] [blame] | 722 | // Skip merging if the block's successor is also a successor to any callbr | 
|  | 723 | // that leads to this block. | 
|  | 724 | // FIXME: Is this really needed? Is this a correctness issue? | 
|  | 725 | for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { | 
|  | 726 | if (auto *CBI = dyn_cast<CallBrInst>((*PI)->getTerminator())) | 
|  | 727 | for (unsigned i = 0, e = CBI->getNumSuccessors(); i != e; ++i) | 
|  | 728 | if (DestBB == CBI->getSuccessor(i)) | 
|  | 729 | return false; | 
|  | 730 | } | 
|  | 731 |  | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 732 | // Try to skip merging if the unique predecessor of BB is terminated by a | 
|  | 733 | // switch or indirect branch instruction, and BB is used as an incoming block | 
|  | 734 | // of PHIs in DestBB. In such case, merging BB and DestBB would cause ISel to | 
|  | 735 | // add COPY instructions in the predecessor of BB instead of BB (if it is not | 
|  | 736 | // merged). Note that the critical edge created by merging such blocks wont be | 
|  | 737 | // split in MachineSink because the jump table is not analyzable. By keeping | 
|  | 738 | // such empty block (BB), ISel will place COPY instructions in BB, not in the | 
|  | 739 | // predecessor of BB. | 
|  | 740 | BasicBlock *Pred = BB->getUniquePredecessor(); | 
|  | 741 | if (!Pred || | 
|  | 742 | !(isa<SwitchInst>(Pred->getTerminator()) || | 
|  | 743 | isa<IndirectBrInst>(Pred->getTerminator()))) | 
|  | 744 | return true; | 
|  | 745 |  | 
| Jonas Devlieghere | 42243df | 2018-08-07 12:14:01 +0000 | [diff] [blame] | 746 | if (BB->getTerminator() != BB->getFirstNonPHIOrDbg()) | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 747 | return true; | 
|  | 748 |  | 
|  | 749 | // We use a simple cost heuristic which determine skipping merging is | 
|  | 750 | // profitable if the cost of skipping merging is less than the cost of | 
|  | 751 | // merging : Cost(skipping merging) < Cost(merging BB), where the | 
|  | 752 | // Cost(skipping merging) is Freq(BB) * (Cost(Copy) + Cost(Branch)), and | 
|  | 753 | // the Cost(merging BB) is Freq(Pred) * Cost(Copy). | 
|  | 754 | // Assuming Cost(Copy) == Cost(Branch), we could simplify it to : | 
|  | 755 | //   Freq(Pred) / Freq(BB) > 2. | 
|  | 756 | // Note that if there are multiple empty blocks sharing the same incoming | 
|  | 757 | // value for the PHIs in the DestBB, we consider them together. In such | 
|  | 758 | // case, Cost(merging BB) will be the sum of their frequencies. | 
|  | 759 |  | 
|  | 760 | if (!isa<PHINode>(DestBB->begin())) | 
|  | 761 | return true; | 
|  | 762 |  | 
|  | 763 | SmallPtrSet<BasicBlock *, 16> SameIncomingValueBBs; | 
|  | 764 |  | 
|  | 765 | // Find all other incoming blocks from which incoming values of all PHIs in | 
|  | 766 | // DestBB are the same as the ones from BB. | 
|  | 767 | for (pred_iterator PI = pred_begin(DestBB), E = pred_end(DestBB); PI != E; | 
|  | 768 | ++PI) { | 
|  | 769 | BasicBlock *DestBBPred = *PI; | 
|  | 770 | if (DestBBPred == BB) | 
|  | 771 | continue; | 
|  | 772 |  | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 773 | if (llvm::all_of(DestBB->phis(), [&](const PHINode &DestPN) { | 
|  | 774 | return DestPN.getIncomingValueForBlock(BB) == | 
|  | 775 | DestPN.getIncomingValueForBlock(DestBBPred); | 
|  | 776 | })) | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 777 | SameIncomingValueBBs.insert(DestBBPred); | 
|  | 778 | } | 
|  | 779 |  | 
|  | 780 | // See if all BB's incoming values are same as the value from Pred. In this | 
|  | 781 | // case, no reason to skip merging because COPYs are expected to be place in | 
|  | 782 | // Pred already. | 
|  | 783 | if (SameIncomingValueBBs.count(Pred)) | 
|  | 784 | return true; | 
|  | 785 |  | 
| Jun Bum Lim | 90b6b50 | 2016-12-16 20:38:39 +0000 | [diff] [blame] | 786 | BlockFrequency PredFreq = BFI->getBlockFreq(Pred); | 
|  | 787 | BlockFrequency BBFreq = BFI->getBlockFreq(BB); | 
|  | 788 |  | 
|  | 789 | for (auto SameValueBB : SameIncomingValueBBs) | 
|  | 790 | if (SameValueBB->getUniquePredecessor() == Pred && | 
|  | 791 | DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB)) | 
|  | 792 | BBFreq += BFI->getBlockFreq(SameValueBB); | 
|  | 793 |  | 
|  | 794 | return PredFreq.getFrequency() <= | 
|  | 795 | BBFreq.getFrequency() * FreqRatioToSkipMerge; | 
|  | 796 | } | 
|  | 797 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 798 | /// Return true if we can merge BB into DestBB if there is a single | 
|  | 799 | /// unconditional branch between them, and BB contains no other non-phi | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 800 | /// instructions. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 801 | bool CodeGenPrepare::canMergeBlocks(const BasicBlock *BB, | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 802 | const BasicBlock *DestBB) const { | 
|  | 803 | // We only want to eliminate blocks whose phi nodes are used by phi nodes in | 
|  | 804 | // the successor.  If there are more complex condition (e.g. preheaders), | 
|  | 805 | // don't mess around with them. | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 806 | for (const PHINode &PN : BB->phis()) { | 
|  | 807 | for (const User *U : PN.users()) { | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 808 | const Instruction *UI = cast<Instruction>(U); | 
|  | 809 | if (UI->getParent() != DestBB || !isa<PHINode>(UI)) | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 810 | return false; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 811 | // If User is inside DestBB block and it is a PHINode then check | 
|  | 812 | // incoming value. If incoming value is not from BB then this is | 
| Devang Patel | d320852 | 2007-04-25 00:37:04 +0000 | [diff] [blame] | 813 | // a complex condition (e.g. preheaders) we want to avoid here. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 814 | if (UI->getParent() == DestBB) { | 
|  | 815 | if (const PHINode *UPN = dyn_cast<PHINode>(UI)) | 
| Devang Patel | d320852 | 2007-04-25 00:37:04 +0000 | [diff] [blame] | 816 | for (unsigned I = 0, E = UPN->getNumIncomingValues(); I != E; ++I) { | 
|  | 817 | Instruction *Insn = dyn_cast<Instruction>(UPN->getIncomingValue(I)); | 
|  | 818 | if (Insn && Insn->getParent() == BB && | 
|  | 819 | Insn->getParent() != UPN->getIncomingBlock(I)) | 
|  | 820 | return false; | 
|  | 821 | } | 
|  | 822 | } | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 823 | } | 
|  | 824 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 825 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 826 | // If BB and DestBB contain any common predecessors, then the phi nodes in BB | 
|  | 827 | // and DestBB may have conflicting incoming values for the block.  If so, we | 
|  | 828 | // can't merge the block. | 
|  | 829 | const PHINode *DestBBPN = dyn_cast<PHINode>(DestBB->begin()); | 
|  | 830 | if (!DestBBPN) return true;  // no conflict. | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 831 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 832 | // Collect the preds of BB. | 
| Chris Lattner | 8201a9b | 2007-11-06 22:07:40 +0000 | [diff] [blame] | 833 | SmallPtrSet<const BasicBlock*, 16> BBPreds; | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 834 | if (const PHINode *BBPN = dyn_cast<PHINode>(BB->begin())) { | 
|  | 835 | // It is faster to get preds from a PHI than with pred_iterator. | 
|  | 836 | for (unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i) | 
|  | 837 | BBPreds.insert(BBPN->getIncomingBlock(i)); | 
|  | 838 | } else { | 
|  | 839 | BBPreds.insert(pred_begin(BB), pred_end(BB)); | 
|  | 840 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 841 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 842 | // Walk the preds of DestBB. | 
|  | 843 | for (unsigned i = 0, e = DestBBPN->getNumIncomingValues(); i != e; ++i) { | 
|  | 844 | BasicBlock *Pred = DestBBPN->getIncomingBlock(i); | 
|  | 845 | if (BBPreds.count(Pred)) {   // Common predecessor? | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 846 | for (const PHINode &PN : DestBB->phis()) { | 
|  | 847 | const Value *V1 = PN.getIncomingValueForBlock(Pred); | 
|  | 848 | const Value *V2 = PN.getIncomingValueForBlock(BB); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 849 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 850 | // If V2 is a phi node in BB, look up what the mapped value will be. | 
|  | 851 | if (const PHINode *V2PN = dyn_cast<PHINode>(V2)) | 
|  | 852 | if (V2PN->getParent() == BB) | 
|  | 853 | V2 = V2PN->getIncomingValueForBlock(Pred); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 854 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 855 | // If there is a conflict, bail out. | 
|  | 856 | if (V1 != V2) return false; | 
|  | 857 | } | 
|  | 858 | } | 
|  | 859 | } | 
|  | 860 |  | 
|  | 861 | return true; | 
|  | 862 | } | 
|  | 863 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 864 | /// Eliminate a basic block that has only phi's and an unconditional branch in | 
|  | 865 | /// it. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 866 | void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) { | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 867 | BranchInst *BI = cast<BranchInst>(BB->getTerminator()); | 
|  | 868 | BasicBlock *DestBB = BI->getSuccessor(0); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 869 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 870 | LLVM_DEBUG(dbgs() << "MERGING MOSTLY EMPTY BLOCKS - BEFORE:\n" | 
|  | 871 | << *BB << *DestBB); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 872 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 873 | // If the destination block has a single pred, then this is a trivial edge, | 
|  | 874 | // just collapse it. | 
| Chris Lattner | 4059f43 | 2008-11-27 19:29:14 +0000 | [diff] [blame] | 875 | if (BasicBlock *SinglePred = DestBB->getSinglePredecessor()) { | 
| Chris Lattner | 8a172da | 2008-11-28 19:54:49 +0000 | [diff] [blame] | 876 | if (SinglePred != DestBB) { | 
| Alina Sbirlea | dfd14ad | 2018-06-20 22:01:04 +0000 | [diff] [blame] | 877 | assert(SinglePred == BB && | 
|  | 878 | "Single predecessor not the same as predecessor"); | 
|  | 879 | // Merge DestBB into SinglePred/BB and delete it. | 
|  | 880 | MergeBlockIntoPredecessor(DestBB); | 
|  | 881 | // Note: BB(=SinglePred) will not be deleted on this path. | 
|  | 882 | // DestBB(=its single successor) is the one that was deleted. | 
|  | 883 | LLVM_DEBUG(dbgs() << "AFTER:\n" << *SinglePred << "\n\n\n"); | 
| Chris Lattner | 8a172da | 2008-11-28 19:54:49 +0000 | [diff] [blame] | 884 | return; | 
|  | 885 | } | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 886 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 887 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 888 | // Otherwise, we have multiple predecessors of BB.  Update the PHIs in DestBB | 
|  | 889 | // to handle the new incoming edges it is about to have. | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 890 | for (PHINode &PN : DestBB->phis()) { | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 891 | // Remove the incoming value for BB, and remember it. | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 892 | Value *InVal = PN.removeIncomingValue(BB, false); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 893 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 894 | // Two options: either the InVal is a phi node defined in BB or it is some | 
|  | 895 | // value that dominates BB. | 
|  | 896 | PHINode *InValPhi = dyn_cast<PHINode>(InVal); | 
|  | 897 | if (InValPhi && InValPhi->getParent() == BB) { | 
|  | 898 | // Add all of the input values of the input PHI as inputs of this phi. | 
|  | 899 | for (unsigned i = 0, e = InValPhi->getNumIncomingValues(); i != e; ++i) | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 900 | PN.addIncoming(InValPhi->getIncomingValue(i), | 
|  | 901 | InValPhi->getIncomingBlock(i)); | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 902 | } else { | 
|  | 903 | // Otherwise, add one instance of the dominating value for each edge that | 
|  | 904 | // we will be adding. | 
|  | 905 | if (PHINode *BBPN = dyn_cast<PHINode>(BB->begin())) { | 
|  | 906 | for (unsigned i = 0, e = BBPN->getNumIncomingValues(); i != e; ++i) | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 907 | PN.addIncoming(InVal, BBPN->getIncomingBlock(i)); | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 908 | } else { | 
| Duncan P. N. Exon Smith | 6c99015 | 2014-07-21 17:06:51 +0000 | [diff] [blame] | 909 | for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 910 | PN.addIncoming(InVal, *PI); | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 911 | } | 
|  | 912 | } | 
|  | 913 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 914 |  | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 915 | // The PHIs are now updated, change everything that refers to BB to use | 
|  | 916 | // DestBB and remove BB. | 
|  | 917 | BB->replaceAllUsesWith(DestBB); | 
|  | 918 | BB->eraseFromParent(); | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 919 | ++NumBlocksElim; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 920 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 921 | LLVM_DEBUG(dbgs() << "AFTER:\n" << *DestBB << "\n\n\n"); | 
| Chris Lattner | c374856 | 2007-04-02 01:35:34 +0000 | [diff] [blame] | 922 | } | 
|  | 923 |  | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 924 | // Computes a map of base pointer relocation instructions to corresponding | 
|  | 925 | // derived pointer relocation instructions given a vector of all relocate calls | 
|  | 926 | static void computeBaseDerivedRelocateMap( | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 927 | const SmallVectorImpl<GCRelocateInst *> &AllRelocateCalls, | 
|  | 928 | DenseMap<GCRelocateInst *, SmallVector<GCRelocateInst *, 2>> | 
|  | 929 | &RelocateInstMap) { | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 930 | // Collect information in two maps: one primarily for locating the base object | 
|  | 931 | // while filling the second map; the second map is the final structure holding | 
|  | 932 | // a mapping between Base and corresponding Derived relocate calls | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 933 | DenseMap<std::pair<unsigned, unsigned>, GCRelocateInst *> RelocateIdxMap; | 
|  | 934 | for (auto *ThisRelocate : AllRelocateCalls) { | 
|  | 935 | auto K = std::make_pair(ThisRelocate->getBasePtrIndex(), | 
|  | 936 | ThisRelocate->getDerivedPtrIndex()); | 
|  | 937 | RelocateIdxMap.insert(std::make_pair(K, ThisRelocate)); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 938 | } | 
|  | 939 | for (auto &Item : RelocateIdxMap) { | 
|  | 940 | std::pair<unsigned, unsigned> Key = Item.first; | 
|  | 941 | if (Key.first == Key.second) | 
|  | 942 | // Base relocation: nothing to insert | 
|  | 943 | continue; | 
|  | 944 |  | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 945 | GCRelocateInst *I = Item.second; | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 946 | auto BaseKey = std::make_pair(Key.first, Key.first); | 
| Sanjoy Das | b818676 | 2015-02-27 02:24:16 +0000 | [diff] [blame] | 947 |  | 
|  | 948 | // We're iterating over RelocateIdxMap so we cannot modify it. | 
|  | 949 | auto MaybeBase = RelocateIdxMap.find(BaseKey); | 
|  | 950 | if (MaybeBase == RelocateIdxMap.end()) | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 951 | // TODO: We might want to insert a new base object relocate and gep off | 
|  | 952 | // that, if there are enough derived object relocates. | 
|  | 953 | continue; | 
| Sanjoy Das | b818676 | 2015-02-27 02:24:16 +0000 | [diff] [blame] | 954 |  | 
|  | 955 | RelocateInstMap[MaybeBase->second].push_back(I); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 956 | } | 
|  | 957 | } | 
|  | 958 |  | 
|  | 959 | // Accepts a GEP and extracts the operands into a vector provided they're all | 
|  | 960 | // small integer constants | 
|  | 961 | static bool getGEPSmallConstantIntOffsetV(GetElementPtrInst *GEP, | 
|  | 962 | SmallVectorImpl<Value *> &OffsetV) { | 
|  | 963 | for (unsigned i = 1; i < GEP->getNumOperands(); i++) { | 
|  | 964 | // Only accept small constant integer operands | 
|  | 965 | auto Op = dyn_cast<ConstantInt>(GEP->getOperand(i)); | 
|  | 966 | if (!Op || Op->getZExtValue() > 20) | 
|  | 967 | return false; | 
|  | 968 | } | 
|  | 969 |  | 
|  | 970 | for (unsigned i = 1; i < GEP->getNumOperands(); i++) | 
|  | 971 | OffsetV.push_back(GEP->getOperand(i)); | 
|  | 972 | return true; | 
|  | 973 | } | 
|  | 974 |  | 
|  | 975 | // Takes a RelocatedBase (base pointer relocation instruction) and Targets to | 
|  | 976 | // replace, computes a replacement, and affects it. | 
|  | 977 | static bool | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 978 | simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase, | 
|  | 979 | const SmallVectorImpl<GCRelocateInst *> &Targets) { | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 980 | bool MadeChange = false; | 
| Serguei Katkov | 9e5604d | 2017-08-17 05:48:30 +0000 | [diff] [blame] | 981 | // We must ensure the relocation of derived pointer is defined after | 
|  | 982 | // relocation of base pointer. If we find a relocation corresponding to base | 
|  | 983 | // defined earlier than relocation of base then we move relocation of base | 
|  | 984 | // right before found relocation. We consider only relocation in the same | 
|  | 985 | // basic block as relocation of base. Relocations from other basic block will | 
|  | 986 | // be skipped by optimization and we do not care about them. | 
|  | 987 | for (auto R = RelocatedBase->getParent()->getFirstInsertionPt(); | 
|  | 988 | &*R != RelocatedBase; ++R) | 
|  | 989 | if (auto RI = dyn_cast<GCRelocateInst>(R)) | 
|  | 990 | if (RI->getStatepoint() == RelocatedBase->getStatepoint()) | 
|  | 991 | if (RI->getBasePtrIndex() == RelocatedBase->getBasePtrIndex()) { | 
|  | 992 | RelocatedBase->moveBefore(RI); | 
|  | 993 | break; | 
|  | 994 | } | 
|  | 995 |  | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 996 | for (GCRelocateInst *ToReplace : Targets) { | 
|  | 997 | assert(ToReplace->getBasePtrIndex() == RelocatedBase->getBasePtrIndex() && | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 998 | "Not relocating a derived object of the original base object"); | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 999 | if (ToReplace->getBasePtrIndex() == ToReplace->getDerivedPtrIndex()) { | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1000 | // A duplicate relocate call. TODO: coalesce duplicates. | 
|  | 1001 | continue; | 
|  | 1002 | } | 
|  | 1003 |  | 
| Igor Laevsky | f637b4a | 2015-11-03 18:37:40 +0000 | [diff] [blame] | 1004 | if (RelocatedBase->getParent() != ToReplace->getParent()) { | 
|  | 1005 | // Base and derived relocates are in different basic blocks. | 
|  | 1006 | // In this case transform is only valid when base dominates derived | 
|  | 1007 | // relocate. However it would be too expensive to check dominance | 
|  | 1008 | // for each such relocate, so we skip the whole transformation. | 
|  | 1009 | continue; | 
|  | 1010 | } | 
|  | 1011 |  | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 1012 | Value *Base = ToReplace->getBasePtr(); | 
|  | 1013 | auto Derived = dyn_cast<GetElementPtrInst>(ToReplace->getDerivedPtr()); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1014 | if (!Derived || Derived->getPointerOperand() != Base) | 
|  | 1015 | continue; | 
|  | 1016 |  | 
|  | 1017 | SmallVector<Value *, 2> OffsetV; | 
|  | 1018 | if (!getGEPSmallConstantIntOffsetV(Derived, OffsetV)) | 
|  | 1019 | continue; | 
|  | 1020 |  | 
|  | 1021 | // Create a Builder and replace the target callsite with a gep | 
| Sanjay Patel | 545a456 | 2016-01-20 18:59:16 +0000 | [diff] [blame] | 1022 | assert(RelocatedBase->getNextNode() && | 
|  | 1023 | "Should always have one since it's not a terminator"); | 
| Sanjoy Das | 3d705e3 | 2015-05-11 23:47:30 +0000 | [diff] [blame] | 1024 |  | 
|  | 1025 | // Insert after RelocatedBase | 
|  | 1026 | IRBuilder<> Builder(RelocatedBase->getNextNode()); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1027 | Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc()); | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1028 |  | 
|  | 1029 | // If gc_relocate does not match the actual type, cast it to the right type. | 
|  | 1030 | // In theory, there must be a bitcast after gc_relocate if the type does not | 
|  | 1031 | // match, and we should reuse it to get the derived pointer. But it could be | 
|  | 1032 | // cases like this: | 
|  | 1033 | // bb1: | 
|  | 1034 | //  ... | 
|  | 1035 | //  %g1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...) | 
|  | 1036 | //  br label %merge | 
|  | 1037 | // | 
|  | 1038 | // bb2: | 
|  | 1039 | //  ... | 
|  | 1040 | //  %g2 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...) | 
|  | 1041 | //  br label %merge | 
|  | 1042 | // | 
|  | 1043 | // merge: | 
|  | 1044 | //  %p1 = phi i8 addrspace(1)* [ %g1, %bb1 ], [ %g2, %bb2 ] | 
|  | 1045 | //  %cast = bitcast i8 addrspace(1)* %p1 in to i32 addrspace(1)* | 
|  | 1046 | // | 
|  | 1047 | // In this case, we can not find the bitcast any more. So we insert a new bitcast | 
|  | 1048 | // no matter there is already one or not. In this way, we can handle all cases, and | 
|  | 1049 | // the extra bitcast should be optimized away in later passes. | 
| Manuel Jacob | 5b90b14 | 2015-12-19 18:38:42 +0000 | [diff] [blame] | 1050 | Value *ActualRelocatedBase = RelocatedBase; | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1051 | if (RelocatedBase->getType() != Base->getType()) { | 
|  | 1052 | ActualRelocatedBase = | 
| Manuel Jacob | 5b90b14 | 2015-12-19 18:38:42 +0000 | [diff] [blame] | 1053 | Builder.CreateBitCast(RelocatedBase, Base->getType()); | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1054 | } | 
| David Blaikie | 68d535c | 2015-03-24 22:38:16 +0000 | [diff] [blame] | 1055 | Value *Replacement = Builder.CreateGEP( | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1056 | Derived->getSourceElementType(), ActualRelocatedBase, makeArrayRef(OffsetV)); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1057 | Replacement->takeName(ToReplace); | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1058 | // If the newly generated derived pointer's type does not match the original derived | 
|  | 1059 | // pointer's type, cast the new derived pointer to match it. Same reasoning as above. | 
| Manuel Jacob | 5b90b14 | 2015-12-19 18:38:42 +0000 | [diff] [blame] | 1060 | Value *ActualReplacement = Replacement; | 
|  | 1061 | if (Replacement->getType() != ToReplace->getType()) { | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1062 | ActualReplacement = | 
| Manuel Jacob | 5b90b14 | 2015-12-19 18:38:42 +0000 | [diff] [blame] | 1063 | Builder.CreateBitCast(Replacement, ToReplace->getType()); | 
| Sanjoy Das | 89c5491 | 2015-05-11 18:49:34 +0000 | [diff] [blame] | 1064 | } | 
|  | 1065 | ToReplace->replaceAllUsesWith(ActualReplacement); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1066 | ToReplace->eraseFromParent(); | 
|  | 1067 |  | 
|  | 1068 | MadeChange = true; | 
|  | 1069 | } | 
|  | 1070 | return MadeChange; | 
|  | 1071 | } | 
|  | 1072 |  | 
|  | 1073 | // Turns this: | 
|  | 1074 | // | 
|  | 1075 | // %base = ... | 
|  | 1076 | // %ptr = gep %base + 15 | 
|  | 1077 | // %tok = statepoint (%fun, i32 0, i32 0, i32 0, %base, %ptr) | 
|  | 1078 | // %base' = relocate(%tok, i32 4, i32 4) | 
|  | 1079 | // %ptr' = relocate(%tok, i32 4, i32 5) | 
|  | 1080 | // %val = load %ptr' | 
|  | 1081 | // | 
|  | 1082 | // into this: | 
|  | 1083 | // | 
|  | 1084 | // %base = ... | 
|  | 1085 | // %ptr = gep %base + 15 | 
|  | 1086 | // %tok = statepoint (%fun, i32 0, i32 0, i32 0, %base, %ptr) | 
|  | 1087 | // %base' = gc.relocate(%tok, i32 4, i32 4) | 
|  | 1088 | // %ptr' = gep %base' + 15 | 
|  | 1089 | // %val = load %ptr' | 
|  | 1090 | bool CodeGenPrepare::simplifyOffsetableRelocate(Instruction &I) { | 
|  | 1091 | bool MadeChange = false; | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 1092 | SmallVector<GCRelocateInst *, 2> AllRelocateCalls; | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1093 |  | 
|  | 1094 | for (auto *U : I.users()) | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 1095 | if (GCRelocateInst *Relocate = dyn_cast<GCRelocateInst>(U)) | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1096 | // Collect all the relocate calls associated with a statepoint | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 1097 | AllRelocateCalls.push_back(Relocate); | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1098 |  | 
| Hans Wennborg | cee62e6 | 2019-11-30 13:23:49 +0100 | [diff] [blame] | 1099 | // We need at least one base pointer relocation + one derived pointer | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1100 | // relocation to mangle | 
|  | 1101 | if (AllRelocateCalls.size() < 2) | 
|  | 1102 | return false; | 
|  | 1103 |  | 
|  | 1104 | // RelocateInstMap is a mapping from the base relocate instruction to the | 
|  | 1105 | // corresponding derived relocate instructions | 
| Manuel Jacob | 83eefa6 | 2016-01-05 04:03:00 +0000 | [diff] [blame] | 1106 | DenseMap<GCRelocateInst *, SmallVector<GCRelocateInst *, 2>> RelocateInstMap; | 
| Ramkumar Ramachandra | dba7329 | 2015-01-14 23:27:07 +0000 | [diff] [blame] | 1107 | computeBaseDerivedRelocateMap(AllRelocateCalls, RelocateInstMap); | 
|  | 1108 | if (RelocateInstMap.empty()) | 
|  | 1109 | return false; | 
|  | 1110 |  | 
|  | 1111 | for (auto &Item : RelocateInstMap) | 
|  | 1112 | // Item.first is the RelocatedBase to offset against | 
|  | 1113 | // Item.second is the vector of Targets to replace | 
|  | 1114 | MadeChange = simplifyRelocatesOffABase(Item.first, Item.second); | 
|  | 1115 | return MadeChange; | 
|  | 1116 | } | 
|  | 1117 |  | 
| Sanjay Patel | 7d8260f | 2019-03-10 18:42:30 +0000 | [diff] [blame] | 1118 | /// Sink the specified cast instruction into its user blocks. | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 1119 | static bool SinkCast(CastInst *CI) { | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1120 | BasicBlock *DefBB = CI->getParent(); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1121 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1122 | /// InsertedCasts - Only insert a cast in each block once. | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1123 | DenseMap<BasicBlock*, CastInst*> InsertedCasts; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1124 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1125 | bool MadeChange = false; | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 1126 | for (Value::user_iterator UI = CI->user_begin(), E = CI->user_end(); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1127 | UI != E; ) { | 
|  | 1128 | Use &TheUse = UI.getUse(); | 
|  | 1129 | Instruction *User = cast<Instruction>(*UI); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1130 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1131 | // Figure out which BB this cast is used in.  For PHI's this is the | 
|  | 1132 | // appropriate predecessor block. | 
|  | 1133 | BasicBlock *UserBB = User->getParent(); | 
|  | 1134 | if (PHINode *PN = dyn_cast<PHINode>(User)) { | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 1135 | UserBB = PN->getIncomingBlock(TheUse); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1136 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1137 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1138 | // Preincrement use iterator so we don't invalidate it. | 
|  | 1139 | ++UI; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1140 |  | 
| David Majnemer | 0c80e2e | 2016-04-27 19:36:38 +0000 | [diff] [blame] | 1141 | // The first insertion point of a block containing an EH pad is after the | 
|  | 1142 | // pad.  If the pad is the user, we cannot sink the cast past the pad. | 
|  | 1143 | if (User->isEHPad()) | 
|  | 1144 | continue; | 
|  | 1145 |  | 
| Andrew Kaylor | d0430e8 | 2015-11-23 19:16:15 +0000 | [diff] [blame] | 1146 | // If the block selected to receive the cast is an EH pad that does not | 
|  | 1147 | // allow non-PHI instructions before the terminator, we can't sink the | 
|  | 1148 | // cast. | 
|  | 1149 | if (UserBB->getTerminator()->isEHPad()) | 
|  | 1150 | continue; | 
|  | 1151 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1152 | // If this user is in the same block as the cast, don't change the cast. | 
|  | 1153 | if (UserBB == DefBB) continue; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1154 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1155 | // If we have already inserted a cast into this block, use it. | 
|  | 1156 | CastInst *&InsertedCast = InsertedCasts[UserBB]; | 
|  | 1157 |  | 
|  | 1158 | if (!InsertedCast) { | 
| Bill Wendling | 8ddfc09 | 2011-08-16 20:45:24 +0000 | [diff] [blame] | 1159 | BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt(); | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1160 | assert(InsertPt != UserBB->end()); | 
|  | 1161 | InsertedCast = CastInst::Create(CI->getOpcode(), CI->getOperand(0), | 
|  | 1162 | CI->getType(), "", &*InsertPt); | 
| Vedant Kumar | 9374c04 | 2018-05-23 22:03:48 +0000 | [diff] [blame] | 1163 | InsertedCast->setDebugLoc(CI->getDebugLoc()); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1164 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1165 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1166 | // Replace a use of the cast with a use of the new cast. | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1167 | TheUse = InsertedCast; | 
| Benjamin Kramer | b4bf14c | 2015-04-10 22:25:36 +0000 | [diff] [blame] | 1168 | MadeChange = true; | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 1169 | ++NumCastUses; | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1170 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1171 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1172 | // If we removed all uses, nuke the cast. | 
| Duncan Sands | afa84da4 | 2008-01-20 16:51:46 +0000 | [diff] [blame] | 1173 | if (CI->use_empty()) { | 
| Adrian Prantl | 261ac8b | 2017-11-03 21:55:03 +0000 | [diff] [blame] | 1174 | salvageDebugInfo(*CI); | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1175 | CI->eraseFromParent(); | 
| Duncan Sands | afa84da4 | 2008-01-20 16:51:46 +0000 | [diff] [blame] | 1176 | MadeChange = true; | 
|  | 1177 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1178 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 1179 | return MadeChange; | 
|  | 1180 | } | 
|  | 1181 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 1182 | /// If the specified cast instruction is a noop copy (e.g. it's casting from | 
|  | 1183 | /// one pointer type to another, i32->i8 on PPC), sink it into user blocks to | 
|  | 1184 | /// reduce the number of virtual registers that must be created and coalesced. | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 1185 | /// | 
|  | 1186 | /// Return true if any changes are made. | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1187 | static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI, | 
|  | 1188 | const DataLayout &DL) { | 
| Justin Lebar | 3e50a5b | 2016-11-21 22:49:15 +0000 | [diff] [blame] | 1189 | // Sink only "cheap" (or nop) address-space casts.  This is a weaker condition | 
|  | 1190 | // than sinking only nop casts, but is helpful on some platforms. | 
|  | 1191 | if (auto *ASC = dyn_cast<AddrSpaceCastInst>(CI)) { | 
| Matt Arsenault | 8dbeb92 | 2019-06-03 18:41:34 +0000 | [diff] [blame] | 1192 | if (!TLI.isFreeAddrSpaceCast(ASC->getSrcAddressSpace(), | 
|  | 1193 | ASC->getDestAddressSpace())) | 
| Justin Lebar | 3e50a5b | 2016-11-21 22:49:15 +0000 | [diff] [blame] | 1194 | return false; | 
|  | 1195 | } | 
|  | 1196 |  | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 1197 | // If this is a noop copy, | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1198 | EVT SrcVT = TLI.getValueType(DL, CI->getOperand(0)->getType()); | 
|  | 1199 | EVT DstVT = TLI.getValueType(DL, CI->getType()); | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 1200 |  | 
|  | 1201 | // This is an fp<->int conversion? | 
|  | 1202 | if (SrcVT.isInteger() != DstVT.isInteger()) | 
|  | 1203 | return false; | 
|  | 1204 |  | 
|  | 1205 | // If this is an extension, it will be a zero or sign extension, which | 
|  | 1206 | // isn't a noop. | 
|  | 1207 | if (SrcVT.bitsLT(DstVT)) return false; | 
|  | 1208 |  | 
|  | 1209 | // If these values will be promoted, find out what they will be promoted | 
|  | 1210 | // to.  This helps us consider truncates on PPC as noop copies when they | 
|  | 1211 | // are. | 
|  | 1212 | if (TLI.getTypeAction(CI->getContext(), SrcVT) == | 
|  | 1213 | TargetLowering::TypePromoteInteger) | 
|  | 1214 | SrcVT = TLI.getTypeToTransformTo(CI->getContext(), SrcVT); | 
|  | 1215 | if (TLI.getTypeAction(CI->getContext(), DstVT) == | 
|  | 1216 | TargetLowering::TypePromoteInteger) | 
|  | 1217 | DstVT = TLI.getTypeToTransformTo(CI->getContext(), DstVT); | 
|  | 1218 |  | 
|  | 1219 | // If, after promotion, these are the same types, this is a noop copy. | 
|  | 1220 | if (SrcVT != DstVT) | 
|  | 1221 | return false; | 
|  | 1222 |  | 
|  | 1223 | return SinkCast(CI); | 
|  | 1224 | } | 
|  | 1225 |  | 
| Teresa Johnson | 4dc8519 | 2019-03-24 15:18:50 +0000 | [diff] [blame] | 1226 | bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO, | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1227 | Value *Arg0, Value *Arg1, | 
| Teresa Johnson | 4dc8519 | 2019-03-24 15:18:50 +0000 | [diff] [blame] | 1228 | CmpInst *Cmp, | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 1229 | Intrinsic::ID IID) { | 
| Sanjay Patel | 5ab41a7 | 2019-05-04 12:46:32 +0000 | [diff] [blame] | 1230 | if (BO->getParent() != Cmp->getParent()) { | 
|  | 1231 | // We used to use a dominator tree here to allow multi-block optimization. | 
|  | 1232 | // But that was problematic because: | 
|  | 1233 | // 1. It could cause a perf regression by hoisting the math op into the | 
|  | 1234 | //    critical path. | 
|  | 1235 | // 2. It could cause a perf regression by creating a value that was live | 
|  | 1236 | //    across multiple blocks and increasing register pressure. | 
|  | 1237 | // 3. Use of a dominator tree could cause large compile-time regression. | 
|  | 1238 | //    This is because we recompute the DT on every change in the main CGP | 
|  | 1239 | //    run-loop. The recomputing is probably unnecessary in many cases, so if | 
|  | 1240 | //    that was fixed, using a DT here would be ok. | 
|  | 1241 | return false; | 
|  | 1242 | } | 
|  | 1243 |  | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1244 | // We allow matching the canonical IR (add X, C) back to (usubo X, -C). | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1245 | if (BO->getOpcode() == Instruction::Add && | 
|  | 1246 | IID == Intrinsic::usub_with_overflow) { | 
|  | 1247 | assert(isa<Constant>(Arg1) && "Unexpected input for usubo"); | 
|  | 1248 | Arg1 = ConstantExpr::getNeg(cast<Constant>(Arg1)); | 
|  | 1249 | } | 
|  | 1250 |  | 
| Sanjay Patel | 5ab41a7 | 2019-05-04 12:46:32 +0000 | [diff] [blame] | 1251 | // Insert at the first instruction of the pair. | 
|  | 1252 | Instruction *InsertPt = nullptr; | 
|  | 1253 | for (Instruction &Iter : *Cmp->getParent()) { | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1254 | // If BO is an XOR, it is not guaranteed that it comes after both inputs to | 
|  | 1255 | // the overflow intrinsic are defined. | 
|  | 1256 | if ((BO->getOpcode() != Instruction::Xor && &Iter == BO) || &Iter == Cmp) { | 
| Sanjay Patel | 5ab41a7 | 2019-05-04 12:46:32 +0000 | [diff] [blame] | 1257 | InsertPt = &Iter; | 
|  | 1258 | break; | 
| Sam Parker | 52760bf | 2019-03-11 13:19:46 +0000 | [diff] [blame] | 1259 | } | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1260 | } | 
| Sanjay Patel | 5ab41a7 | 2019-05-04 12:46:32 +0000 | [diff] [blame] | 1261 | assert(InsertPt != nullptr && "Parent block did not contain cmp or binop"); | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1262 |  | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1263 | IRBuilder<> Builder(InsertPt); | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1264 | Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1); | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1265 | if (BO->getOpcode() != Instruction::Xor) { | 
|  | 1266 | Value *Math = Builder.CreateExtractValue(MathOV, 0, "math"); | 
|  | 1267 | BO->replaceAllUsesWith(Math); | 
|  | 1268 | } else | 
|  | 1269 | assert(BO->hasOneUse() && | 
|  | 1270 | "Patterns with XOr should use the BO only in the compare"); | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1271 | Value *OV = Builder.CreateExtractValue(MathOV, 1, "ov"); | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1272 | Cmp->replaceAllUsesWith(OV); | 
| Florian Hahn | c7fc0e5 | 2020-02-19 19:35:32 +0100 | [diff] [blame] | 1273 | Cmp->eraseFromParent(); | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1274 | BO->eraseFromParent(); | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1275 | return true; | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1276 | } | 
|  | 1277 |  | 
| Sanjay Patel | cb04ba0 | 2019-02-24 15:31:27 +0000 | [diff] [blame] | 1278 | /// Match special-case patterns that check for unsigned add overflow. | 
|  | 1279 | static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, | 
|  | 1280 | BinaryOperator *&Add) { | 
|  | 1281 | // Add = add A, 1; Cmp = icmp eq A,-1 (overflow if A is max val) | 
|  | 1282 | // Add = add A,-1; Cmp = icmp ne A, 0 (overflow if A is non-zero) | 
|  | 1283 | Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1); | 
| Sanjay Patel | 3b2d0bc | 2019-03-04 22:47:13 +0000 | [diff] [blame] | 1284 |  | 
|  | 1285 | // We are not expecting non-canonical/degenerate code. Just bail out. | 
|  | 1286 | if (isa<Constant>(A)) | 
|  | 1287 | return false; | 
|  | 1288 |  | 
| Sanjay Patel | cb04ba0 | 2019-02-24 15:31:27 +0000 | [diff] [blame] | 1289 | ICmpInst::Predicate Pred = Cmp->getPredicate(); | 
|  | 1290 | if (Pred == ICmpInst::ICMP_EQ && match(B, m_AllOnes())) | 
|  | 1291 | B = ConstantInt::get(B->getType(), 1); | 
|  | 1292 | else if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) | 
|  | 1293 | B = ConstantInt::get(B->getType(), -1); | 
|  | 1294 | else | 
|  | 1295 | return false; | 
|  | 1296 |  | 
|  | 1297 | // Check the users of the variable operand of the compare looking for an add | 
|  | 1298 | // with the adjusted constant. | 
|  | 1299 | for (User *U : A->users()) { | 
|  | 1300 | if (match(U, m_Add(m_Specific(A), m_Specific(B)))) { | 
|  | 1301 | Add = cast<BinaryOperator>(U); | 
|  | 1302 | return true; | 
|  | 1303 | } | 
|  | 1304 | } | 
|  | 1305 | return false; | 
|  | 1306 | } | 
|  | 1307 |  | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1308 | /// Try to combine the compare into a call to the llvm.uadd.with.overflow | 
|  | 1309 | /// intrinsic. Return true if any changes were made. | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1310 | bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp, | 
|  | 1311 | bool &ModifiedDT) { | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1312 | Value *A, *B; | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1313 | BinaryOperator *Add; | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1314 | if (!match(Cmp, m_UAddWithOverflow(m_Value(A), m_Value(B), m_BinOp(Add)))) { | 
| Sanjay Patel | cb04ba0 | 2019-02-24 15:31:27 +0000 | [diff] [blame] | 1315 | if (!matchUAddWithOverflowConstantEdgeCases(Cmp, Add)) | 
|  | 1316 | return false; | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1317 | // Set A and B in case we match matchUAddWithOverflowConstantEdgeCases. | 
|  | 1318 | A = Add->getOperand(0); | 
|  | 1319 | B = Add->getOperand(1); | 
|  | 1320 | } | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1321 |  | 
| Teresa Johnson | 4dc8519 | 2019-03-24 15:18:50 +0000 | [diff] [blame] | 1322 | if (!TLI->shouldFormOverflowOp(ISD::UADDO, | 
| Florian Hahn | 216afd3 | 2020-02-19 10:00:59 +0100 | [diff] [blame] | 1323 | TLI->getValueType(*DL, Add->getType()), | 
|  | 1324 | Add->hasNUsesOrMore(2))) | 
| Sanjay Patel | 84ceae6 | 2019-02-03 17:53:09 +0000 | [diff] [blame] | 1325 | return false; | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1326 |  | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1327 | // We don't want to move around uses of condition values this late, so we | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1328 | // check if it is legal to create the call to the intrinsic in the basic | 
| Sanjay Patel | c00bdab4 | 2019-02-04 16:30:46 +0000 | [diff] [blame] | 1329 | // block containing the icmp. | 
|  | 1330 | if (Add->getParent() != Cmp->getParent() && !Add->hasOneUse()) | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1331 | return false; | 
|  | 1332 |  | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1333 | if (!replaceMathCmpWithIntrinsic(Add, A, B, Cmp, | 
|  | 1334 | Intrinsic::uadd_with_overflow)) | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1335 | return false; | 
|  | 1336 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1337 | // Reset callers - do not crash by iterating over a dead instruction. | 
|  | 1338 | ModifiedDT = true; | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1339 | return true; | 
|  | 1340 | } | 
|  | 1341 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1342 | bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp, | 
|  | 1343 | bool &ModifiedDT) { | 
| Sanjay Patel | 2c9275a | 2019-03-14 23:14:31 +0000 | [diff] [blame] | 1344 | // We are not expecting non-canonical/degenerate code. Just bail out. | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1345 | Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1); | 
| Sanjay Patel | 2c9275a | 2019-03-14 23:14:31 +0000 | [diff] [blame] | 1346 | if (isa<Constant>(A) && isa<Constant>(B)) | 
|  | 1347 | return false; | 
|  | 1348 |  | 
|  | 1349 | // Convert (A u> B) to (A u< B) to simplify pattern matching. | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1350 | ICmpInst::Predicate Pred = Cmp->getPredicate(); | 
|  | 1351 | if (Pred == ICmpInst::ICMP_UGT) { | 
|  | 1352 | std::swap(A, B); | 
|  | 1353 | Pred = ICmpInst::ICMP_ULT; | 
|  | 1354 | } | 
|  | 1355 | // Convert special-case: (A == 0) is the same as (A u< 1). | 
|  | 1356 | if (Pred == ICmpInst::ICMP_EQ && match(B, m_ZeroInt())) { | 
|  | 1357 | B = ConstantInt::get(B->getType(), 1); | 
|  | 1358 | Pred = ICmpInst::ICMP_ULT; | 
|  | 1359 | } | 
| Sanjay Patel | 198cc30 | 2019-02-20 21:23:04 +0000 | [diff] [blame] | 1360 | // Convert special-case: (A != 0) is the same as (0 u< A). | 
|  | 1361 | if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) { | 
|  | 1362 | std::swap(A, B); | 
|  | 1363 | Pred = ICmpInst::ICMP_ULT; | 
|  | 1364 | } | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1365 | if (Pred != ICmpInst::ICMP_ULT) | 
|  | 1366 | return false; | 
|  | 1367 |  | 
|  | 1368 | // Walk the users of a variable operand of a compare looking for a subtract or | 
|  | 1369 | // add with that same operand. Also match the 2nd operand of the compare to | 
|  | 1370 | // the add/sub, but that may be a negated constant operand of an add. | 
|  | 1371 | Value *CmpVariableOperand = isa<Constant>(A) ? B : A; | 
|  | 1372 | BinaryOperator *Sub = nullptr; | 
|  | 1373 | for (User *U : CmpVariableOperand->users()) { | 
|  | 1374 | // A - B, A u< B --> usubo(A, B) | 
|  | 1375 | if (match(U, m_Sub(m_Specific(A), m_Specific(B)))) { | 
|  | 1376 | Sub = cast<BinaryOperator>(U); | 
|  | 1377 | break; | 
|  | 1378 | } | 
|  | 1379 |  | 
|  | 1380 | // A + (-C), A u< C (canonicalized form of (sub A, C)) | 
|  | 1381 | const APInt *CmpC, *AddC; | 
|  | 1382 | if (match(U, m_Add(m_Specific(A), m_APInt(AddC))) && | 
|  | 1383 | match(B, m_APInt(CmpC)) && *AddC == -(*CmpC)) { | 
|  | 1384 | Sub = cast<BinaryOperator>(U); | 
|  | 1385 | break; | 
|  | 1386 | } | 
|  | 1387 | } | 
|  | 1388 | if (!Sub) | 
|  | 1389 | return false; | 
|  | 1390 |  | 
| Teresa Johnson | 4dc8519 | 2019-03-24 15:18:50 +0000 | [diff] [blame] | 1391 | if (!TLI->shouldFormOverflowOp(ISD::USUBO, | 
| Florian Hahn | 216afd3 | 2020-02-19 10:00:59 +0100 | [diff] [blame] | 1392 | TLI->getValueType(*DL, Sub->getType()), | 
|  | 1393 | Sub->hasNUsesOrMore(2))) | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1394 | return false; | 
|  | 1395 |  | 
| Florian Hahn | 7769030 | 2020-02-23 16:32:55 +0000 | [diff] [blame] | 1396 | if (!replaceMathCmpWithIntrinsic(Sub, Sub->getOperand(0), Sub->getOperand(1), | 
|  | 1397 | Cmp, Intrinsic::usub_with_overflow)) | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1398 | return false; | 
| Sanjay Patel | ffe1cf5 | 2019-02-22 20:20:24 +0000 | [diff] [blame] | 1399 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1400 | // Reset callers - do not crash by iterating over a dead instruction. | 
|  | 1401 | ModifiedDT = true; | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1402 | return true; | 
|  | 1403 | } | 
|  | 1404 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 1405 | /// Sink the given CmpInst into user blocks to reduce the number of virtual | 
|  | 1406 | /// registers that must be created and coalesced. This is a clear win except on | 
|  | 1407 | /// targets with multiple condition code registers (PowerPC), where it might | 
|  | 1408 | /// lose; some adjustment may be wanted there. | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1409 | /// | 
|  | 1410 | /// Return true if any changes are made. | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1411 | static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI) { | 
|  | 1412 | if (TLI.hasMultipleConditionRegisters()) | 
|  | 1413 | return false; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1414 |  | 
| Peter Zotov | 0b6d7bc | 2016-04-03 16:36:17 +0000 | [diff] [blame] | 1415 | // Avoid sinking soft-FP comparisons, since this can move them into a loop. | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1416 | if (TLI.useSoftFloat() && isa<FCmpInst>(Cmp)) | 
| Peter Zotov | 0b6d7bc | 2016-04-03 16:36:17 +0000 | [diff] [blame] | 1417 | return false; | 
|  | 1418 |  | 
|  | 1419 | // Only insert a cmp in each block once. | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1420 | DenseMap<BasicBlock*, CmpInst*> InsertedCmps; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1421 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1422 | bool MadeChange = false; | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1423 | for (Value::user_iterator UI = Cmp->user_begin(), E = Cmp->user_end(); | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1424 | UI != E; ) { | 
|  | 1425 | Use &TheUse = UI.getUse(); | 
|  | 1426 | Instruction *User = cast<Instruction>(*UI); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1427 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1428 | // Preincrement use iterator so we don't invalidate it. | 
|  | 1429 | ++UI; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1430 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1431 | // Don't bother for PHI nodes. | 
|  | 1432 | if (isa<PHINode>(User)) | 
|  | 1433 | continue; | 
|  | 1434 |  | 
|  | 1435 | // Figure out which BB this cmp is used in. | 
|  | 1436 | BasicBlock *UserBB = User->getParent(); | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1437 | BasicBlock *DefBB = Cmp->getParent(); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1438 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1439 | // If this user is in the same block as the cmp, don't change the cmp. | 
|  | 1440 | if (UserBB == DefBB) continue; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1441 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1442 | // If we have already inserted a cmp into this block, use it. | 
|  | 1443 | CmpInst *&InsertedCmp = InsertedCmps[UserBB]; | 
|  | 1444 |  | 
|  | 1445 | if (!InsertedCmp) { | 
| Bill Wendling | 8ddfc09 | 2011-08-16 20:45:24 +0000 | [diff] [blame] | 1446 | BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt(); | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1447 | assert(InsertPt != UserBB->end()); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1448 | InsertedCmp = | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1449 | CmpInst::Create(Cmp->getOpcode(), Cmp->getPredicate(), | 
|  | 1450 | Cmp->getOperand(0), Cmp->getOperand(1), "", | 
|  | 1451 | &*InsertPt); | 
| Wolfgang Pieb | e51bede | 2016-10-06 21:43:45 +0000 | [diff] [blame] | 1452 | // Propagate the debug info. | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1453 | InsertedCmp->setDebugLoc(Cmp->getDebugLoc()); | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1454 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1455 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1456 | // Replace a use of the cmp with a use of the new cmp. | 
|  | 1457 | TheUse = InsertedCmp; | 
| Benjamin Kramer | b4bf14c | 2015-04-10 22:25:36 +0000 | [diff] [blame] | 1458 | MadeChange = true; | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 1459 | ++NumCmpUses; | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1460 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1461 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1462 | // If we removed all uses, nuke the cmp. | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 1463 | if (Cmp->use_empty()) { | 
|  | 1464 | Cmp->eraseFromParent(); | 
| Benjamin Kramer | b4bf14c | 2015-04-10 22:25:36 +0000 | [diff] [blame] | 1465 | MadeChange = true; | 
|  | 1466 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 1467 |  | 
| Dale Johannesen | edfec0b | 2007-06-12 16:50:17 +0000 | [diff] [blame] | 1468 | return MadeChange; | 
|  | 1469 | } | 
|  | 1470 |  | 
| Yi-Hong Lyu | 6bbfafd | 2019-11-11 16:15:52 +0000 | [diff] [blame] | 1471 | /// For pattern like: | 
|  | 1472 | /// | 
|  | 1473 | ///   DomCond = icmp sgt/slt CmpOp0, CmpOp1 (might not be in DomBB) | 
|  | 1474 | ///   ... | 
|  | 1475 | /// DomBB: | 
|  | 1476 | ///   ... | 
|  | 1477 | ///   br DomCond, TrueBB, CmpBB | 
|  | 1478 | /// CmpBB: (with DomBB being the single predecessor) | 
|  | 1479 | ///   ... | 
|  | 1480 | ///   Cmp = icmp eq CmpOp0, CmpOp1 | 
|  | 1481 | ///   ... | 
|  | 1482 | /// | 
|  | 1483 | /// It would use two comparison on targets that lowering of icmp sgt/slt is | 
|  | 1484 | /// different from lowering of icmp eq (PowerPC). This function try to convert | 
|  | 1485 | /// 'Cmp = icmp eq CmpOp0, CmpOp1' to ' Cmp = icmp slt/sgt CmpOp0, CmpOp1'. | 
|  | 1486 | /// After that, DomCond and Cmp can use the same comparison so reduce one | 
|  | 1487 | /// comparison. | 
|  | 1488 | /// | 
|  | 1489 | /// Return true if any changes are made. | 
|  | 1490 | static bool foldICmpWithDominatingICmp(CmpInst *Cmp, | 
|  | 1491 | const TargetLowering &TLI) { | 
|  | 1492 | if (!EnableICMP_EQToICMP_ST && TLI.isEqualityCmpFoldedWithSignedCmp()) | 
|  | 1493 | return false; | 
|  | 1494 |  | 
|  | 1495 | ICmpInst::Predicate Pred = Cmp->getPredicate(); | 
|  | 1496 | if (Pred != ICmpInst::ICMP_EQ) | 
|  | 1497 | return false; | 
|  | 1498 |  | 
|  | 1499 | // If icmp eq has users other than BranchInst and SelectInst, converting it to | 
|  | 1500 | // icmp slt/sgt would introduce more redundant LLVM IR. | 
|  | 1501 | for (User *U : Cmp->users()) { | 
|  | 1502 | if (isa<BranchInst>(U)) | 
|  | 1503 | continue; | 
|  | 1504 | if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == Cmp) | 
|  | 1505 | continue; | 
|  | 1506 | return false; | 
|  | 1507 | } | 
|  | 1508 |  | 
|  | 1509 | // This is a cheap/incomplete check for dominance - just match a single | 
|  | 1510 | // predecessor with a conditional branch. | 
|  | 1511 | BasicBlock *CmpBB = Cmp->getParent(); | 
|  | 1512 | BasicBlock *DomBB = CmpBB->getSinglePredecessor(); | 
|  | 1513 | if (!DomBB) | 
|  | 1514 | return false; | 
|  | 1515 |  | 
|  | 1516 | // We want to ensure that the only way control gets to the comparison of | 
|  | 1517 | // interest is that a less/greater than comparison on the same operands is | 
|  | 1518 | // false. | 
|  | 1519 | Value *DomCond; | 
|  | 1520 | BasicBlock *TrueBB, *FalseBB; | 
|  | 1521 | if (!match(DomBB->getTerminator(), m_Br(m_Value(DomCond), TrueBB, FalseBB))) | 
|  | 1522 | return false; | 
|  | 1523 | if (CmpBB != FalseBB) | 
|  | 1524 | return false; | 
|  | 1525 |  | 
|  | 1526 | Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1); | 
|  | 1527 | ICmpInst::Predicate DomPred; | 
|  | 1528 | if (!match(DomCond, m_ICmp(DomPred, m_Specific(CmpOp0), m_Specific(CmpOp1)))) | 
|  | 1529 | return false; | 
|  | 1530 | if (DomPred != ICmpInst::ICMP_SGT && DomPred != ICmpInst::ICMP_SLT) | 
|  | 1531 | return false; | 
|  | 1532 |  | 
|  | 1533 | // Convert the equality comparison to the opposite of the dominating | 
|  | 1534 | // comparison and swap the direction for all branch/select users. | 
|  | 1535 | // We have conceptually converted: | 
|  | 1536 | // Res = (a < b) ? <LT_RES> : (a == b) ? <EQ_RES> : <GT_RES>; | 
|  | 1537 | // to | 
|  | 1538 | // Res = (a < b) ? <LT_RES> : (a > b)  ? <GT_RES> : <EQ_RES>; | 
|  | 1539 | // And similarly for branches. | 
|  | 1540 | for (User *U : Cmp->users()) { | 
|  | 1541 | if (auto *BI = dyn_cast<BranchInst>(U)) { | 
|  | 1542 | assert(BI->isConditional() && "Must be conditional"); | 
|  | 1543 | BI->swapSuccessors(); | 
|  | 1544 | continue; | 
|  | 1545 | } | 
|  | 1546 | if (auto *SI = dyn_cast<SelectInst>(U)) { | 
|  | 1547 | // Swap operands | 
|  | 1548 | SI->swapValues(); | 
|  | 1549 | SI->swapProfMetadata(); | 
|  | 1550 | continue; | 
|  | 1551 | } | 
|  | 1552 | llvm_unreachable("Must be a branch or a select"); | 
|  | 1553 | } | 
|  | 1554 | Cmp->setPredicate(CmpInst::getSwappedPredicate(DomPred)); | 
|  | 1555 | return true; | 
|  | 1556 | } | 
|  | 1557 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1558 | bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, bool &ModifiedDT) { | 
| Teresa Johnson | 4dc8519 | 2019-03-24 15:18:50 +0000 | [diff] [blame] | 1559 | if (sinkCmpExpression(Cmp, *TLI)) | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1560 | return true; | 
|  | 1561 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1562 | if (combineToUAddWithOverflow(Cmp, ModifiedDT)) | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1563 | return true; | 
|  | 1564 |  | 
| Evgeniy Stepanov | 46ec57e | 2019-05-03 17:31:49 +0000 | [diff] [blame] | 1565 | if (combineToUSubWithOverflow(Cmp, ModifiedDT)) | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 1566 | return true; | 
|  | 1567 |  | 
| Yi-Hong Lyu | 6bbfafd | 2019-11-11 16:15:52 +0000 | [diff] [blame] | 1568 | if (foldICmpWithDominatingICmp(Cmp, *TLI)) | 
|  | 1569 | return true; | 
|  | 1570 |  | 
| Sanjoy Das | b6c5914 | 2015-04-10 21:07:09 +0000 | [diff] [blame] | 1571 | return false; | 
|  | 1572 | } | 
|  | 1573 |  | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 1574 | /// Duplicate and sink the given 'and' instruction into user blocks where it is | 
|  | 1575 | /// used in a compare to allow isel to generate better code for targets where | 
|  | 1576 | /// this operation can be combined. | 
|  | 1577 | /// | 
|  | 1578 | /// Return true if any changes are made. | 
|  | 1579 | static bool sinkAndCmp0Expression(Instruction *AndI, | 
|  | 1580 | const TargetLowering &TLI, | 
|  | 1581 | SetOfInstrs &InsertedInsts) { | 
|  | 1582 | // Double-check that we're not trying to optimize an instruction that was | 
|  | 1583 | // already optimized by some other part of this pass. | 
|  | 1584 | assert(!InsertedInsts.count(AndI) && | 
|  | 1585 | "Attempting to optimize already optimized and instruction"); | 
|  | 1586 | (void) InsertedInsts; | 
|  | 1587 |  | 
|  | 1588 | // Nothing to do for single use in same basic block. | 
|  | 1589 | if (AndI->hasOneUse() && | 
|  | 1590 | AndI->getParent() == cast<Instruction>(*AndI->user_begin())->getParent()) | 
|  | 1591 | return false; | 
|  | 1592 |  | 
|  | 1593 | // Try to avoid cases where sinking/duplicating is likely to increase register | 
|  | 1594 | // pressure. | 
|  | 1595 | if (!isa<ConstantInt>(AndI->getOperand(0)) && | 
|  | 1596 | !isa<ConstantInt>(AndI->getOperand(1)) && | 
|  | 1597 | AndI->getOperand(0)->hasOneUse() && AndI->getOperand(1)->hasOneUse()) | 
|  | 1598 | return false; | 
|  | 1599 |  | 
|  | 1600 | for (auto *U : AndI->users()) { | 
|  | 1601 | Instruction *User = cast<Instruction>(U); | 
|  | 1602 |  | 
| Sanjay Patel | 7d8260f | 2019-03-10 18:42:30 +0000 | [diff] [blame] | 1603 | // Only sink 'and' feeding icmp with 0. | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 1604 | if (!isa<ICmpInst>(User)) | 
|  | 1605 | return false; | 
|  | 1606 |  | 
|  | 1607 | auto *CmpC = dyn_cast<ConstantInt>(User->getOperand(1)); | 
|  | 1608 | if (!CmpC || !CmpC->isZero()) | 
|  | 1609 | return false; | 
|  | 1610 | } | 
|  | 1611 |  | 
|  | 1612 | if (!TLI.isMaskAndCmp0FoldingBeneficial(*AndI)) | 
|  | 1613 | return false; | 
|  | 1614 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 1615 | LLVM_DEBUG(dbgs() << "found 'and' feeding only icmp 0;\n"); | 
|  | 1616 | LLVM_DEBUG(AndI->getParent()->dump()); | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 1617 |  | 
|  | 1618 | // Push the 'and' into the same block as the icmp 0.  There should only be | 
|  | 1619 | // one (icmp (and, 0)) in each block, since CSE/GVN should have removed any | 
|  | 1620 | // others, so we don't need to keep track of which BBs we insert into. | 
|  | 1621 | for (Value::user_iterator UI = AndI->user_begin(), E = AndI->user_end(); | 
|  | 1622 | UI != E; ) { | 
|  | 1623 | Use &TheUse = UI.getUse(); | 
|  | 1624 | Instruction *User = cast<Instruction>(*UI); | 
|  | 1625 |  | 
|  | 1626 | // Preincrement use iterator so we don't invalidate it. | 
|  | 1627 | ++UI; | 
|  | 1628 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 1629 | LLVM_DEBUG(dbgs() << "sinking 'and' use: " << *User << "\n"); | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 1630 |  | 
|  | 1631 | // Keep the 'and' in the same place if the use is already in the same block. | 
|  | 1632 | Instruction *InsertPt = | 
|  | 1633 | User->getParent() == AndI->getParent() ? AndI : User; | 
|  | 1634 | Instruction *InsertedAnd = | 
|  | 1635 | BinaryOperator::Create(Instruction::And, AndI->getOperand(0), | 
|  | 1636 | AndI->getOperand(1), "", InsertPt); | 
|  | 1637 | // Propagate the debug info. | 
|  | 1638 | InsertedAnd->setDebugLoc(AndI->getDebugLoc()); | 
|  | 1639 |  | 
|  | 1640 | // Replace a use of the 'and' with a use of the new 'and'. | 
|  | 1641 | TheUse = InsertedAnd; | 
|  | 1642 | ++NumAndUses; | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 1643 | LLVM_DEBUG(User->getParent()->dump()); | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 1644 | } | 
|  | 1645 |  | 
|  | 1646 | // We removed all uses, nuke the and. | 
|  | 1647 | AndI->eraseFromParent(); | 
|  | 1648 | return true; | 
|  | 1649 | } | 
|  | 1650 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 1651 | /// Check if the candidates could be combined with a shift instruction, which | 
|  | 1652 | /// includes: | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1653 | /// 1. Truncate instruction | 
|  | 1654 | /// 2. And instruction and the imm is a mask of the low bits: | 
|  | 1655 | /// imm & (imm+1) == 0 | 
| Benjamin Kramer | 322053c | 2014-04-27 14:54:59 +0000 | [diff] [blame] | 1656 | static bool isExtractBitsCandidateUse(Instruction *User) { | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1657 | if (!isa<TruncInst>(User)) { | 
|  | 1658 | if (User->getOpcode() != Instruction::And || | 
|  | 1659 | !isa<ConstantInt>(User->getOperand(1))) | 
|  | 1660 | return false; | 
|  | 1661 |  | 
| Quentin Colombet | d4f4469 | 2014-04-22 01:20:34 +0000 | [diff] [blame] | 1662 | const APInt &Cimm = cast<ConstantInt>(User->getOperand(1))->getValue(); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1663 |  | 
| Quentin Colombet | d4f4469 | 2014-04-22 01:20:34 +0000 | [diff] [blame] | 1664 | if ((Cimm & (Cimm + 1)).getBoolValue()) | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1665 | return false; | 
|  | 1666 | } | 
|  | 1667 | return true; | 
|  | 1668 | } | 
|  | 1669 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 1670 | /// Sink both shift and truncate instruction to the use of truncate's BB. | 
| Benjamin Kramer | 322053c | 2014-04-27 14:54:59 +0000 | [diff] [blame] | 1671 | static bool | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1672 | SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, | 
|  | 1673 | DenseMap<BasicBlock *, BinaryOperator *> &InsertedShifts, | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1674 | const TargetLowering &TLI, const DataLayout &DL) { | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1675 | BasicBlock *UserBB = User->getParent(); | 
|  | 1676 | DenseMap<BasicBlock *, CastInst *> InsertedTruncs; | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 1677 | auto *TruncI = cast<TruncInst>(User); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1678 | bool MadeChange = false; | 
|  | 1679 |  | 
|  | 1680 | for (Value::user_iterator TruncUI = TruncI->user_begin(), | 
|  | 1681 | TruncE = TruncI->user_end(); | 
|  | 1682 | TruncUI != TruncE;) { | 
|  | 1683 |  | 
|  | 1684 | Use &TruncTheUse = TruncUI.getUse(); | 
|  | 1685 | Instruction *TruncUser = cast<Instruction>(*TruncUI); | 
|  | 1686 | // Preincrement use iterator so we don't invalidate it. | 
|  | 1687 |  | 
|  | 1688 | ++TruncUI; | 
|  | 1689 |  | 
|  | 1690 | int ISDOpcode = TLI.InstructionOpcodeToISD(TruncUser->getOpcode()); | 
|  | 1691 | if (!ISDOpcode) | 
|  | 1692 | continue; | 
|  | 1693 |  | 
| Tim Northover | e2239ff | 2014-07-29 10:20:22 +0000 | [diff] [blame] | 1694 | // If the use is actually a legal node, there will not be an | 
|  | 1695 | // implicit truncate. | 
|  | 1696 | // FIXME: always querying the result type is just an | 
|  | 1697 | // approximation; some nodes' legality is determined by the | 
|  | 1698 | // operand or other means. There's no good way to find out though. | 
| Ahmed Bougacha | 0788d49 | 2014-11-12 22:16:55 +0000 | [diff] [blame] | 1699 | if (TLI.isOperationLegalOrCustom( | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1700 | ISDOpcode, TLI.getValueType(DL, TruncUser->getType(), true))) | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1701 | continue; | 
|  | 1702 |  | 
|  | 1703 | // Don't bother for PHI nodes. | 
|  | 1704 | if (isa<PHINode>(TruncUser)) | 
|  | 1705 | continue; | 
|  | 1706 |  | 
|  | 1707 | BasicBlock *TruncUserBB = TruncUser->getParent(); | 
|  | 1708 |  | 
|  | 1709 | if (UserBB == TruncUserBB) | 
|  | 1710 | continue; | 
|  | 1711 |  | 
|  | 1712 | BinaryOperator *&InsertedShift = InsertedShifts[TruncUserBB]; | 
|  | 1713 | CastInst *&InsertedTrunc = InsertedTruncs[TruncUserBB]; | 
|  | 1714 |  | 
|  | 1715 | if (!InsertedShift && !InsertedTrunc) { | 
|  | 1716 | BasicBlock::iterator InsertPt = TruncUserBB->getFirstInsertionPt(); | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1717 | assert(InsertPt != TruncUserBB->end()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1718 | // Sink the shift | 
|  | 1719 | if (ShiftI->getOpcode() == Instruction::AShr) | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1720 | InsertedShift = BinaryOperator::CreateAShr(ShiftI->getOperand(0), CI, | 
|  | 1721 | "", &*InsertPt); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1722 | else | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1723 | InsertedShift = BinaryOperator::CreateLShr(ShiftI->getOperand(0), CI, | 
|  | 1724 | "", &*InsertPt); | 
| Vedant Kumar | 1b02dad | 2018-09-15 04:08:52 +0000 | [diff] [blame] | 1725 | InsertedShift->setDebugLoc(ShiftI->getDebugLoc()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1726 |  | 
|  | 1727 | // Sink the trunc | 
|  | 1728 | BasicBlock::iterator TruncInsertPt = TruncUserBB->getFirstInsertionPt(); | 
|  | 1729 | TruncInsertPt++; | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1730 | assert(TruncInsertPt != TruncUserBB->end()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1731 |  | 
|  | 1732 | InsertedTrunc = CastInst::Create(TruncI->getOpcode(), InsertedShift, | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1733 | TruncI->getType(), "", &*TruncInsertPt); | 
| Vedant Kumar | 1b02dad | 2018-09-15 04:08:52 +0000 | [diff] [blame] | 1734 | InsertedTrunc->setDebugLoc(TruncI->getDebugLoc()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1735 |  | 
|  | 1736 | MadeChange = true; | 
|  | 1737 |  | 
|  | 1738 | TruncTheUse = InsertedTrunc; | 
|  | 1739 | } | 
|  | 1740 | } | 
|  | 1741 | return MadeChange; | 
|  | 1742 | } | 
|  | 1743 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 1744 | /// Sink the shift *right* instruction into user blocks if the uses could | 
|  | 1745 | /// potentially be combined with this shift instruction and generate BitExtract | 
|  | 1746 | /// instruction. It will only be applied if the architecture supports BitExtract | 
|  | 1747 | /// instruction. Here is an example: | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1748 | /// BB1: | 
|  | 1749 | ///   %x.extract.shift = lshr i64 %arg1, 32 | 
|  | 1750 | /// BB2: | 
|  | 1751 | ///   %x.extract.trunc = trunc i64 %x.extract.shift to i16 | 
|  | 1752 | /// ==> | 
|  | 1753 | /// | 
|  | 1754 | /// BB2: | 
|  | 1755 | ///   %x.extract.shift.1 = lshr i64 %arg1, 32 | 
|  | 1756 | ///   %x.extract.trunc = trunc i64 %x.extract.shift.1 to i16 | 
|  | 1757 | /// | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 1758 | /// CodeGen will recognize the pattern in BB2 and generate BitExtract | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1759 | /// instruction. | 
|  | 1760 | /// Return true if any changes are made. | 
|  | 1761 | static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI, | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1762 | const TargetLowering &TLI, | 
|  | 1763 | const DataLayout &DL) { | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1764 | BasicBlock *DefBB = ShiftI->getParent(); | 
|  | 1765 |  | 
|  | 1766 | /// Only insert instructions in each block once. | 
|  | 1767 | DenseMap<BasicBlock *, BinaryOperator *> InsertedShifts; | 
|  | 1768 |  | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1769 | bool shiftIsLegal = TLI.isTypeLegal(TLI.getValueType(DL, ShiftI->getType())); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1770 |  | 
|  | 1771 | bool MadeChange = false; | 
|  | 1772 | for (Value::user_iterator UI = ShiftI->user_begin(), E = ShiftI->user_end(); | 
|  | 1773 | UI != E;) { | 
|  | 1774 | Use &TheUse = UI.getUse(); | 
|  | 1775 | Instruction *User = cast<Instruction>(*UI); | 
|  | 1776 | // Preincrement use iterator so we don't invalidate it. | 
|  | 1777 | ++UI; | 
|  | 1778 |  | 
|  | 1779 | // Don't bother for PHI nodes. | 
|  | 1780 | if (isa<PHINode>(User)) | 
|  | 1781 | continue; | 
|  | 1782 |  | 
|  | 1783 | if (!isExtractBitsCandidateUse(User)) | 
|  | 1784 | continue; | 
|  | 1785 |  | 
|  | 1786 | BasicBlock *UserBB = User->getParent(); | 
|  | 1787 |  | 
|  | 1788 | if (UserBB == DefBB) { | 
|  | 1789 | // If the shift and truncate instruction are in the same BB. The use of | 
|  | 1790 | // the truncate(TruncUse) may still introduce another truncate if not | 
|  | 1791 | // legal. In this case, we would like to sink both shift and truncate | 
|  | 1792 | // instruction to the BB of TruncUse. | 
|  | 1793 | // for example: | 
|  | 1794 | // BB1: | 
|  | 1795 | // i64 shift.result = lshr i64 opnd, imm | 
|  | 1796 | // trunc.result = trunc shift.result to i16 | 
|  | 1797 | // | 
|  | 1798 | // BB2: | 
|  | 1799 | //   ----> We will have an implicit truncate here if the architecture does | 
|  | 1800 | //   not have i16 compare. | 
|  | 1801 | // cmp i16 trunc.result, opnd2 | 
|  | 1802 | // | 
|  | 1803 | if (isa<TruncInst>(User) && shiftIsLegal | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 1804 | // If the type of the truncate is legal, no truncate will be | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1805 | // introduced in other basic blocks. | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1806 | && | 
|  | 1807 | (!TLI.isTypeLegal(TLI.getValueType(DL, User->getType())))) | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1808 | MadeChange = | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 1809 | SinkShiftAndTruncate(ShiftI, User, CI, InsertedShifts, TLI, DL); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1810 |  | 
|  | 1811 | continue; | 
|  | 1812 | } | 
|  | 1813 | // If we have already inserted a shift into this block, use it. | 
|  | 1814 | BinaryOperator *&InsertedShift = InsertedShifts[UserBB]; | 
|  | 1815 |  | 
|  | 1816 | if (!InsertedShift) { | 
|  | 1817 | BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt(); | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1818 | assert(InsertPt != UserBB->end()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1819 |  | 
|  | 1820 | if (ShiftI->getOpcode() == Instruction::AShr) | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1821 | InsertedShift = BinaryOperator::CreateAShr(ShiftI->getOperand(0), CI, | 
|  | 1822 | "", &*InsertPt); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1823 | else | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 1824 | InsertedShift = BinaryOperator::CreateLShr(ShiftI->getOperand(0), CI, | 
|  | 1825 | "", &*InsertPt); | 
| Vedant Kumar | 1b02dad | 2018-09-15 04:08:52 +0000 | [diff] [blame] | 1826 | InsertedShift->setDebugLoc(ShiftI->getDebugLoc()); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1827 |  | 
|  | 1828 | MadeChange = true; | 
|  | 1829 | } | 
|  | 1830 |  | 
|  | 1831 | // Replace a use of the shift with a use of the new shift. | 
|  | 1832 | TheUse = InsertedShift; | 
|  | 1833 | } | 
|  | 1834 |  | 
| Sanjay Patel | acceedb | 2019-08-16 23:10:34 +0000 | [diff] [blame] | 1835 | // If we removed all uses, or there are none, nuke the shift. | 
| Vedant Kumar | 1b02dad | 2018-09-15 04:08:52 +0000 | [diff] [blame] | 1836 | if (ShiftI->use_empty()) { | 
|  | 1837 | salvageDebugInfo(*ShiftI); | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1838 | ShiftI->eraseFromParent(); | 
| Sanjay Patel | acceedb | 2019-08-16 23:10:34 +0000 | [diff] [blame] | 1839 | MadeChange = true; | 
| Vedant Kumar | 1b02dad | 2018-09-15 04:08:52 +0000 | [diff] [blame] | 1840 | } | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 1841 |  | 
|  | 1842 | return MadeChange; | 
|  | 1843 | } | 
|  | 1844 |  | 
| Sanjay Patel | 4699b8a | 2015-11-19 16:37:10 +0000 | [diff] [blame] | 1845 | /// If counting leading or trailing zeros is an expensive operation and a zero | 
|  | 1846 | /// input is defined, add a check for zero to avoid calling the intrinsic. | 
|  | 1847 | /// | 
|  | 1848 | /// We want to transform: | 
|  | 1849 | ///     %z = call i64 @llvm.cttz.i64(i64 %A, i1 false) | 
|  | 1850 | /// | 
|  | 1851 | /// into: | 
|  | 1852 | ///   entry: | 
|  | 1853 | ///     %cmpz = icmp eq i64 %A, 0 | 
|  | 1854 | ///     br i1 %cmpz, label %cond.end, label %cond.false | 
|  | 1855 | ///   cond.false: | 
|  | 1856 | ///     %z = call i64 @llvm.cttz.i64(i64 %A, i1 true) | 
|  | 1857 | ///     br label %cond.end | 
|  | 1858 | ///   cond.end: | 
|  | 1859 | ///     %ctz = phi i64 [ 64, %entry ], [ %z, %cond.false ] | 
|  | 1860 | /// | 
|  | 1861 | /// If the transform is performed, return true and set ModifiedDT to true. | 
|  | 1862 | static bool despeculateCountZeros(IntrinsicInst *CountZeros, | 
|  | 1863 | const TargetLowering *TLI, | 
|  | 1864 | const DataLayout *DL, | 
|  | 1865 | bool &ModifiedDT) { | 
| Sanjay Patel | 4699b8a | 2015-11-19 16:37:10 +0000 | [diff] [blame] | 1866 | // If a zero input is undefined, it doesn't make sense to despeculate that. | 
|  | 1867 | if (match(CountZeros->getOperand(1), m_One())) | 
|  | 1868 | return false; | 
|  | 1869 |  | 
|  | 1870 | // If it's cheap to speculate, there's nothing to do. | 
|  | 1871 | auto IntrinsicID = CountZeros->getIntrinsicID(); | 
|  | 1872 | if ((IntrinsicID == Intrinsic::cttz && TLI->isCheapToSpeculateCttz()) || | 
|  | 1873 | (IntrinsicID == Intrinsic::ctlz && TLI->isCheapToSpeculateCtlz())) | 
|  | 1874 | return false; | 
|  | 1875 |  | 
|  | 1876 | // Only handle legal scalar cases. Anything else requires too much work. | 
|  | 1877 | Type *Ty = CountZeros->getType(); | 
|  | 1878 | unsigned SizeInBits = Ty->getPrimitiveSizeInBits(); | 
| Jun Bum Lim | be11bdc | 2016-05-13 18:38:35 +0000 | [diff] [blame] | 1879 | if (Ty->isVectorTy() || SizeInBits > DL->getLargestLegalIntTypeSizeInBits()) | 
| Sanjay Patel | 4699b8a | 2015-11-19 16:37:10 +0000 | [diff] [blame] | 1880 | return false; | 
|  | 1881 |  | 
|  | 1882 | // The intrinsic will be sunk behind a compare against zero and branch. | 
|  | 1883 | BasicBlock *StartBlock = CountZeros->getParent(); | 
|  | 1884 | BasicBlock *CallBlock = StartBlock->splitBasicBlock(CountZeros, "cond.false"); | 
|  | 1885 |  | 
|  | 1886 | // Create another block after the count zero intrinsic. A PHI will be added | 
|  | 1887 | // in this block to select the result of the intrinsic or the bit-width | 
|  | 1888 | // constant if the input to the intrinsic is zero. | 
|  | 1889 | BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(CountZeros)); | 
|  | 1890 | BasicBlock *EndBlock = CallBlock->splitBasicBlock(SplitPt, "cond.end"); | 
|  | 1891 |  | 
|  | 1892 | // Set up a builder to create a compare, conditional branch, and PHI. | 
|  | 1893 | IRBuilder<> Builder(CountZeros->getContext()); | 
|  | 1894 | Builder.SetInsertPoint(StartBlock->getTerminator()); | 
|  | 1895 | Builder.SetCurrentDebugLocation(CountZeros->getDebugLoc()); | 
|  | 1896 |  | 
|  | 1897 | // Replace the unconditional branch that was created by the first split with | 
|  | 1898 | // a compare against zero and a conditional branch. | 
|  | 1899 | Value *Zero = Constant::getNullValue(Ty); | 
|  | 1900 | Value *Cmp = Builder.CreateICmpEQ(CountZeros->getOperand(0), Zero, "cmpz"); | 
|  | 1901 | Builder.CreateCondBr(Cmp, EndBlock, CallBlock); | 
|  | 1902 | StartBlock->getTerminator()->eraseFromParent(); | 
|  | 1903 |  | 
|  | 1904 | // Create a PHI in the end block to select either the output of the intrinsic | 
|  | 1905 | // or the bit width of the operand. | 
|  | 1906 | Builder.SetInsertPoint(&EndBlock->front()); | 
|  | 1907 | PHINode *PN = Builder.CreatePHI(Ty, 2, "ctz"); | 
|  | 1908 | CountZeros->replaceAllUsesWith(PN); | 
|  | 1909 | Value *BitWidth = Builder.getInt(APInt(SizeInBits, SizeInBits)); | 
|  | 1910 | PN->addIncoming(BitWidth, StartBlock); | 
|  | 1911 | PN->addIncoming(CountZeros, CallBlock); | 
|  | 1912 |  | 
|  | 1913 | // We are explicitly handling the zero case, so we can set the intrinsic's | 
|  | 1914 | // undefined zero argument to 'true'. This will also prevent reprocessing the | 
|  | 1915 | // intrinsic; we only despeculate when a zero input is defined. | 
|  | 1916 | CountZeros->setArgOperand(1, Builder.getTrue()); | 
|  | 1917 | ModifiedDT = true; | 
|  | 1918 | return true; | 
|  | 1919 | } | 
|  | 1920 |  | 
| Sanjay Patel | 3b8974b | 2017-06-08 20:00:09 +0000 | [diff] [blame] | 1921 | bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) { | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 1922 | BasicBlock *BB = CI->getParent(); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 1923 |  | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 1924 | // Lower inline assembly if we can. | 
|  | 1925 | // If we found an inline asm expession, and if the target knows how to | 
|  | 1926 | // lower it to normal LLVM code, do so now. | 
| Craig Topper | a58b62b | 2020-04-27 20:15:59 -0700 | [diff] [blame] | 1927 | if (CI->isInlineAsm()) { | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 1928 | if (TLI->ExpandInlineAsm(CI)) { | 
|  | 1929 | // Avoid invalidating the iterator. | 
|  | 1930 | CurInstIterator = BB->begin(); | 
|  | 1931 | // Avoid processing instructions out of order, which could cause | 
|  | 1932 | // reuse before a value is defined. | 
|  | 1933 | SunkAddrs.clear(); | 
|  | 1934 | return true; | 
|  | 1935 | } | 
|  | 1936 | // Sink address computing for memory operands into the block. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 1937 | if (optimizeInlineAsmInst(CI)) | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 1938 | return true; | 
|  | 1939 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 1940 |  | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1941 | // Align the pointer arguments to this call if the target thinks it's a good | 
|  | 1942 | // idea | 
|  | 1943 | unsigned MinSize, PrefAlign; | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 1944 | if (TLI->shouldAlignPointerArgs(CI, MinSize, PrefAlign)) { | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1945 | for (auto &Arg : CI->arg_operands()) { | 
|  | 1946 | // We want to align both objects whose address is used directly and | 
|  | 1947 | // objects whose address is used in casts and GEPs, though it only makes | 
|  | 1948 | // sense for GEPs if the offset is a multiple of the desired alignment and | 
|  | 1949 | // if size - offset meets the size threshold. | 
|  | 1950 | if (!Arg->getType()->isPointerTy()) | 
|  | 1951 | continue; | 
| Elena Demikhovsky | 945b7e5 | 2018-02-14 06:58:08 +0000 | [diff] [blame] | 1952 | APInt Offset(DL->getIndexSizeInBits( | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 1953 | cast<PointerType>(Arg->getType())->getAddressSpace()), | 
|  | 1954 | 0); | 
|  | 1955 | Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*DL, Offset); | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1956 | uint64_t Offset2 = Offset.getLimitedValue(); | 
| John Brawn | e8fd6c8 | 2015-04-13 10:47:39 +0000 | [diff] [blame] | 1957 | if ((Offset2 & (PrefAlign-1)) != 0) | 
|  | 1958 | continue; | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1959 | AllocaInst *AI; | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 1960 | if ((AI = dyn_cast<AllocaInst>(Val)) && AI->getAlignment() < PrefAlign && | 
|  | 1961 | DL->getTypeAllocSize(AI->getAllocatedType()) >= MinSize + Offset2) | 
| Eli Friedman | 4f04db4 | 2020-05-15 13:23:14 -0700 | [diff] [blame] | 1962 | AI->setAlignment(Align(PrefAlign)); | 
| John Brawn | e8fd6c8 | 2015-04-13 10:47:39 +0000 | [diff] [blame] | 1963 | // Global variables can only be aligned if they are defined in this | 
|  | 1964 | // object (i.e. they are uniquely initialized in this object), and | 
|  | 1965 | // over-aligning global variables that have an explicit section is | 
|  | 1966 | // forbidden. | 
|  | 1967 | GlobalVariable *GV; | 
| James Y Knight | ac03dca | 2016-01-15 16:33:06 +0000 | [diff] [blame] | 1968 | if ((GV = dyn_cast<GlobalVariable>(Val)) && GV->canIncreaseAlignment() && | 
| Tim Northover | 918f050 | 2016-07-18 18:28:52 +0000 | [diff] [blame] | 1969 | GV->getPointerAlignment(*DL) < PrefAlign && | 
| Manuel Jacob | 5f6eaac | 2016-01-16 20:30:46 +0000 | [diff] [blame] | 1970 | DL->getTypeAllocSize(GV->getValueType()) >= | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 1971 | MinSize + Offset2) | 
| Guillaume Chatelet | 0e62011 | 2019-10-15 11:24:36 +0000 | [diff] [blame] | 1972 | GV->setAlignment(MaybeAlign(PrefAlign)); | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1973 | } | 
|  | 1974 | // If this is a memcpy (or similar) then we may be able to improve the | 
|  | 1975 | // alignment | 
|  | 1976 | if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(CI)) { | 
| Craig Topper | 68b2e50 | 2020-04-20 20:32:05 -0700 | [diff] [blame] | 1977 | Align DestAlign = getKnownAlignment(MI->getDest(), *DL); | 
|  | 1978 | MaybeAlign MIDestAlign = MI->getDestAlign(); | 
|  | 1979 | if (!MIDestAlign || DestAlign > *MIDestAlign) | 
| Daniel Neilson | be58a22 | 2018-01-31 17:24:53 +0000 | [diff] [blame] | 1980 | MI->setDestAlignment(DestAlign); | 
|  | 1981 | if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { | 
| Craig Topper | 68b2e50 | 2020-04-20 20:32:05 -0700 | [diff] [blame] | 1982 | MaybeAlign MTISrcAlign = MTI->getSourceAlign(); | 
|  | 1983 | Align SrcAlign = getKnownAlignment(MTI->getSource(), *DL); | 
|  | 1984 | if (!MTISrcAlign || SrcAlign > *MTISrcAlign) | 
| Daniel Neilson | be58a22 | 2018-01-31 17:24:53 +0000 | [diff] [blame] | 1985 | MTI->setSourceAlignment(SrcAlign); | 
|  | 1986 | } | 
| John Brawn | 0dbcd65 | 2015-03-18 12:01:59 +0000 | [diff] [blame] | 1987 | } | 
|  | 1988 | } | 
|  | 1989 |  | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 1990 | // If we have a cold call site, try to sink addressing computation into the | 
|  | 1991 | // cold block.  This interacts with our handling for loads and stores to | 
|  | 1992 | // ensure that we can fold all uses of a potential addressing computation | 
|  | 1993 | // into their uses.  TODO: generalize this to work over profiling data | 
| Matt Arsenault | 23b7609 | 2020-01-31 14:35:53 -0500 | [diff] [blame] | 1994 | if (CI->hasFnAttr(Attribute::Cold) && | 
|  | 1995 | !OptSize && !llvm::shouldOptimizeForSize(BB, PSI, BFI.get())) | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 1996 | for (auto &Arg : CI->arg_operands()) { | 
|  | 1997 | if (!Arg->getType()->isPointerTy()) | 
|  | 1998 | continue; | 
|  | 1999 | unsigned AS = Arg->getType()->getPointerAddressSpace(); | 
|  | 2000 | return optimizeMemoryInst(CI, Arg, Arg->getType(), AS); | 
|  | 2001 | } | 
| Junmo Park | 6098cbb | 2016-03-11 07:05:32 +0000 | [diff] [blame] | 2002 |  | 
| Eric Christopher | 4b7948e | 2010-03-11 02:41:03 +0000 | [diff] [blame] | 2003 | IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI); | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 2004 | if (II) { | 
|  | 2005 | switch (II->getIntrinsicID()) { | 
|  | 2006 | default: break; | 
| Guozhi Wei | 6d20937 | 2020-03-31 11:55:51 -0700 | [diff] [blame] | 2007 | case Intrinsic::assume: { | 
|  | 2008 | II->eraseFromParent(); | 
|  | 2009 | return true; | 
|  | 2010 | } | 
|  | 2011 |  | 
| Philip Reames | ede49dd | 2019-01-31 18:45:46 +0000 | [diff] [blame] | 2012 | case Intrinsic::experimental_widenable_condition: { | 
|  | 2013 | // Give up on future widening oppurtunties so that we can fold away dead | 
|  | 2014 | // paths and merge blocks before going into block-local instruction | 
| Jim Lin | 466f884 | 2020-02-18 10:48:38 +0800 | [diff] [blame] | 2015 | // selection. | 
| Philip Reames | ede49dd | 2019-01-31 18:45:46 +0000 | [diff] [blame] | 2016 | if (II->use_empty()) { | 
|  | 2017 | II->eraseFromParent(); | 
|  | 2018 | return true; | 
|  | 2019 | } | 
|  | 2020 | Constant *RetVal = ConstantInt::getTrue(II->getContext()); | 
|  | 2021 | resetIteratorIfInvalidatedWhileCalling(BB, [&]() { | 
|  | 2022 | replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr); | 
|  | 2023 | }); | 
|  | 2024 | return true; | 
|  | 2025 | } | 
| Joerg Sonnenberger | 9681ea9 | 2019-10-14 16:15:14 +0000 | [diff] [blame] | 2026 | case Intrinsic::objectsize: | 
|  | 2027 | llvm_unreachable("llvm.objectsize.* should have been lowered already"); | 
|  | 2028 | case Intrinsic::is_constant: | 
|  | 2029 | llvm_unreachable("llvm.is.constant.* should have been lowered already"); | 
| Ahmed Bougacha | 236f904 | 2015-05-22 21:37:17 +0000 | [diff] [blame] | 2030 | case Intrinsic::aarch64_stlxr: | 
|  | 2031 | case Intrinsic::aarch64_stxr: { | 
|  | 2032 | ZExtInst *ExtVal = dyn_cast<ZExtInst>(CI->getArgOperand(0)); | 
|  | 2033 | if (!ExtVal || !ExtVal->hasOneUse() || | 
|  | 2034 | ExtVal->getParent() == CI->getParent()) | 
|  | 2035 | return false; | 
|  | 2036 | // Sink a zext feeding stlxr/stxr before it, so it can be folded into it. | 
|  | 2037 | ExtVal->moveBefore(CI); | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 2038 | // Mark this instruction as "inserted by CGP", so that other | 
|  | 2039 | // optimizations don't touch it. | 
|  | 2040 | InsertedInsts.insert(ExtVal); | 
| Ahmed Bougacha | 236f904 | 2015-05-22 21:37:17 +0000 | [diff] [blame] | 2041 | return true; | 
|  | 2042 | } | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 2043 |  | 
| Piotr Padlewski | 5dde809 | 2018-05-03 11:03:01 +0000 | [diff] [blame] | 2044 | case Intrinsic::launder_invariant_group: | 
| Krzysztof Pszeniczny | 2bfe759 | 2018-10-19 19:02:16 +0000 | [diff] [blame] | 2045 | case Intrinsic::strip_invariant_group: { | 
|  | 2046 | Value *ArgVal = II->getArgOperand(0); | 
|  | 2047 | auto it = LargeOffsetGEPMap.find(II); | 
|  | 2048 | if (it != LargeOffsetGEPMap.end()) { | 
|  | 2049 | // Merge entries in LargeOffsetGEPMap to reflect the RAUW. | 
|  | 2050 | // Make sure not to have to deal with iterator invalidation | 
|  | 2051 | // after possibly adding ArgVal to LargeOffsetGEPMap. | 
|  | 2052 | auto GEPs = std::move(it->second); | 
|  | 2053 | LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end()); | 
|  | 2054 | LargeOffsetGEPMap.erase(II); | 
|  | 2055 | } | 
|  | 2056 |  | 
|  | 2057 | II->replaceAllUsesWith(ArgVal); | 
| Piotr Padlewski | 6c15ec4 | 2015-09-15 18:32:14 +0000 | [diff] [blame] | 2058 | II->eraseFromParent(); | 
|  | 2059 | return true; | 
| Krzysztof Pszeniczny | 2bfe759 | 2018-10-19 19:02:16 +0000 | [diff] [blame] | 2060 | } | 
| Sanjay Patel | 4699b8a | 2015-11-19 16:37:10 +0000 | [diff] [blame] | 2061 | case Intrinsic::cttz: | 
|  | 2062 | case Intrinsic::ctlz: | 
|  | 2063 | // If counting zeros is expensive, try to avoid it. | 
|  | 2064 | return despeculateCountZeros(II, TLI, DL, ModifiedDT); | 
| Sanjay Patel | 5be37cb | 2020-05-15 15:22:30 -0400 | [diff] [blame] | 2065 | case Intrinsic::fshl: | 
|  | 2066 | case Intrinsic::fshr: | 
|  | 2067 | return optimizeFunnelShift(II); | 
| Jeremy Morse | c93a9b1 | 2019-12-06 11:21:27 +0000 | [diff] [blame] | 2068 | case Intrinsic::dbg_value: | 
|  | 2069 | return fixupDbgValue(II); | 
| Sander de Smalen | 67d4c99 | 2020-01-21 10:20:27 +0000 | [diff] [blame] | 2070 | case Intrinsic::vscale: { | 
|  | 2071 | // If datalayout has no special restrictions on vector data layout, | 
|  | 2072 | // replace `llvm.vscale` by an equivalent constant expression | 
|  | 2073 | // to benefit from cheap constant propagation. | 
|  | 2074 | Type *ScalableVectorTy = | 
|  | 2075 | VectorType::get(Type::getInt8Ty(II->getContext()), 1, true); | 
|  | 2076 | if (DL->getTypeAllocSize(ScalableVectorTy).getKnownMinSize() == 8) { | 
|  | 2077 | auto Null = Constant::getNullValue(ScalableVectorTy->getPointerTo()); | 
|  | 2078 | auto One = ConstantInt::getSigned(II->getType(), 1); | 
|  | 2079 | auto *CGep = | 
|  | 2080 | ConstantExpr::getGetElementPtr(ScalableVectorTy, Null, One); | 
|  | 2081 | II->replaceAllUsesWith(ConstantExpr::getPtrToInt(CGep, II->getType())); | 
|  | 2082 | II->eraseFromParent(); | 
|  | 2083 | return true; | 
|  | 2084 | } | 
| Craig Topper | 944cc5e | 2020-04-16 17:03:16 -0700 | [diff] [blame] | 2085 | break; | 
| Sander de Smalen | 67d4c99 | 2020-01-21 10:20:27 +0000 | [diff] [blame] | 2086 | } | 
| Craig Topper | 944cc5e | 2020-04-16 17:03:16 -0700 | [diff] [blame] | 2087 | case Intrinsic::masked_gather: | 
|  | 2088 | return optimizeGatherScatterInst(II, II->getArgOperand(0)); | 
|  | 2089 | case Intrinsic::masked_scatter: | 
|  | 2090 | return optimizeGatherScatterInst(II, II->getArgOperand(1)); | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 2091 | } | 
| Eric Christopher | 4b7948e | 2010-03-11 02:41:03 +0000 | [diff] [blame] | 2092 |  | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 2093 | SmallVector<Value *, 2> PtrOps; | 
|  | 2094 | Type *AccessTy; | 
|  | 2095 | if (TLI->getAddrModeArguments(II, PtrOps, AccessTy)) | 
|  | 2096 | while (!PtrOps.empty()) { | 
|  | 2097 | Value *PtrVal = PtrOps.pop_back_val(); | 
|  | 2098 | unsigned AS = PtrVal->getType()->getPointerAddressSpace(); | 
|  | 2099 | if (optimizeMemoryInst(II, PtrVal, AccessTy, AS)) | 
|  | 2100 | return true; | 
|  | 2101 | } | 
| Pete Cooper | 615fd89 | 2012-03-13 20:59:56 +0000 | [diff] [blame] | 2102 | } | 
|  | 2103 |  | 
| Eric Christopher | 4b7948e | 2010-03-11 02:41:03 +0000 | [diff] [blame] | 2104 | // From here on out we're working with named functions. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 2105 | if (!CI->getCalledFunction()) return false; | 
| Devang Patel | 0da5250 | 2011-05-26 21:51:06 +0000 | [diff] [blame] | 2106 |  | 
| Benjamin Kramer | 7b88a49 | 2010-03-12 09:27:41 +0000 | [diff] [blame] | 2107 | // Lower all default uses of _chk calls.  This is very similar | 
|  | 2108 | // to what InstCombineCalls does, but here we are only lowering calls | 
| Ahmed Bougacha | e03bef7 | 2015-01-12 17:22:43 +0000 | [diff] [blame] | 2109 | // to fortified library functions (e.g. __memcpy_chk) that have the default | 
|  | 2110 | // "don't know" as the objectsize.  Anything else should be left alone. | 
| Mehdi Amini | a28d91d | 2015-03-10 02:37:25 +0000 | [diff] [blame] | 2111 | FortifiedLibCallSimplifier Simplifier(TLInfo, true); | 
| Nikita Popov | a8db806 | 2020-02-18 22:20:55 +0100 | [diff] [blame] | 2112 | IRBuilder<> Builder(CI); | 
|  | 2113 | if (Value *V = Simplifier.optimizeCall(CI, Builder)) { | 
| Ahmed Bougacha | e03bef7 | 2015-01-12 17:22:43 +0000 | [diff] [blame] | 2114 | CI->replaceAllUsesWith(V); | 
|  | 2115 | CI->eraseFromParent(); | 
|  | 2116 | return true; | 
|  | 2117 | } | 
| Zaara Syeda | 3a7578c | 2017-05-31 17:12:38 +0000 | [diff] [blame] | 2118 |  | 
| Ahmed Bougacha | e03bef7 | 2015-01-12 17:22:43 +0000 | [diff] [blame] | 2119 | return false; | 
| Eric Christopher | 4b7948e | 2010-03-11 02:41:03 +0000 | [diff] [blame] | 2120 | } | 
| Chris Lattner | 1b93be5 | 2011-01-15 07:25:29 +0000 | [diff] [blame] | 2121 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 2122 | /// Look for opportunities to duplicate return instructions to the predecessor | 
|  | 2123 | /// to enable tail call optimizations. The case it is currently looking for is: | 
| Dmitri Gribenko | 2bc1d48 | 2012-09-13 12:34:29 +0000 | [diff] [blame] | 2124 | /// @code | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2125 | /// bb0: | 
|  | 2126 | ///   %tmp0 = tail call i32 @f0() | 
|  | 2127 | ///   br label %return | 
|  | 2128 | /// bb1: | 
|  | 2129 | ///   %tmp1 = tail call i32 @f1() | 
|  | 2130 | ///   br label %return | 
|  | 2131 | /// bb2: | 
|  | 2132 | ///   %tmp2 = tail call i32 @f2() | 
|  | 2133 | ///   br label %return | 
|  | 2134 | /// return: | 
|  | 2135 | ///   %retval = phi i32 [ %tmp0, %bb0 ], [ %tmp1, %bb1 ], [ %tmp2, %bb2 ] | 
|  | 2136 | ///   ret i32 %retval | 
| Dmitri Gribenko | 2bc1d48 | 2012-09-13 12:34:29 +0000 | [diff] [blame] | 2137 | /// @endcode | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2138 | /// | 
|  | 2139 | /// => | 
|  | 2140 | /// | 
| Dmitri Gribenko | 2bc1d48 | 2012-09-13 12:34:29 +0000 | [diff] [blame] | 2141 | /// @code | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2142 | /// bb0: | 
|  | 2143 | ///   %tmp0 = tail call i32 @f0() | 
|  | 2144 | ///   ret i32 %tmp0 | 
|  | 2145 | /// bb1: | 
|  | 2146 | ///   %tmp1 = tail call i32 @f1() | 
|  | 2147 | ///   ret i32 %tmp1 | 
|  | 2148 | /// bb2: | 
|  | 2149 | ///   %tmp2 = tail call i32 @f2() | 
|  | 2150 | ///   ret i32 %tmp2 | 
| Dmitri Gribenko | 2bc1d48 | 2012-09-13 12:34:29 +0000 | [diff] [blame] | 2151 | /// @endcode | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 2152 | bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT) { | 
| Michael Kuperstein | 7132156 | 2016-09-07 20:29:49 +0000 | [diff] [blame] | 2153 | ReturnInst *RetI = dyn_cast<ReturnInst>(BB->getTerminator()); | 
|  | 2154 | if (!RetI) | 
| Benjamin Kramer | 455fa35 | 2012-11-23 19:17:06 +0000 | [diff] [blame] | 2155 | return false; | 
|  | 2156 |  | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 2157 | PHINode *PN = nullptr; | 
| Guozhi Wei | ee9a3eb | 2020-03-04 11:10:32 -0800 | [diff] [blame] | 2158 | ExtractValueInst *EVI = nullptr; | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 2159 | BitCastInst *BCI = nullptr; | 
| Michael Kuperstein | 7132156 | 2016-09-07 20:29:49 +0000 | [diff] [blame] | 2160 | Value *V = RetI->getReturnValue(); | 
| Evan Cheng | 249716e | 2012-07-27 21:21:26 +0000 | [diff] [blame] | 2161 | if (V) { | 
|  | 2162 | BCI = dyn_cast<BitCastInst>(V); | 
|  | 2163 | if (BCI) | 
|  | 2164 | V = BCI->getOperand(0); | 
|  | 2165 |  | 
| Guozhi Wei | ee9a3eb | 2020-03-04 11:10:32 -0800 | [diff] [blame] | 2166 | EVI = dyn_cast<ExtractValueInst>(V); | 
|  | 2167 | if (EVI) { | 
|  | 2168 | V = EVI->getOperand(0); | 
|  | 2169 | if (!std::all_of(EVI->idx_begin(), EVI->idx_end(), | 
|  | 2170 | [](unsigned idx) { return idx == 0; })) | 
|  | 2171 | return false; | 
|  | 2172 | } | 
|  | 2173 |  | 
| Evan Cheng | 249716e | 2012-07-27 21:21:26 +0000 | [diff] [blame] | 2174 | PN = dyn_cast<PHINode>(V); | 
|  | 2175 | if (!PN) | 
|  | 2176 | return false; | 
|  | 2177 | } | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2178 |  | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2179 | if (PN && PN->getParent() != BB) | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2180 | return false; | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2181 |  | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2182 | // Make sure there are no instructions between the PHI and return, or that the | 
|  | 2183 | // return is the first instruction in the block. | 
|  | 2184 | if (PN) { | 
|  | 2185 | BasicBlock::iterator BI = BB->begin(); | 
| Jonas Paulsson | 5ed4d46 | 2019-01-29 09:03:35 +0000 | [diff] [blame] | 2186 | // Skip over debug and the bitcast. | 
| Guozhi Wei | ee9a3eb | 2020-03-04 11:10:32 -0800 | [diff] [blame] | 2187 | do { | 
|  | 2188 | ++BI; | 
|  | 2189 | } while (isa<DbgInfoIntrinsic>(BI) || &*BI == BCI || &*BI == EVI); | 
| Michael Kuperstein | 7132156 | 2016-09-07 20:29:49 +0000 | [diff] [blame] | 2190 | if (&*BI != RetI) | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2191 | return false; | 
|  | 2192 | } else { | 
| Cameron Zwarich | 74157ab | 2011-03-24 16:34:59 +0000 | [diff] [blame] | 2193 | BasicBlock::iterator BI = BB->begin(); | 
|  | 2194 | while (isa<DbgInfoIntrinsic>(BI)) ++BI; | 
| Michael Kuperstein | 7132156 | 2016-09-07 20:29:49 +0000 | [diff] [blame] | 2195 | if (&*BI != RetI) | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2196 | return false; | 
|  | 2197 | } | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2198 |  | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2199 | /// Only dup the ReturnInst if the CallInst is likely to be emitted as a tail | 
|  | 2200 | /// call. | 
| Michael Kuperstein | f79af6f | 2016-09-08 00:48:37 +0000 | [diff] [blame] | 2201 | const Function *F = BB->getParent(); | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2202 | SmallVector<BasicBlock*, 4> TailCallBBs; | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2203 | if (PN) { | 
|  | 2204 | for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) { | 
| Francis Visoiu Mistrih | 1646851 | 2019-04-23 21:57:46 +0000 | [diff] [blame] | 2205 | // Look through bitcasts. | 
|  | 2206 | Value *IncomingVal = PN->getIncomingValue(I)->stripPointerCasts(); | 
|  | 2207 | CallInst *CI = dyn_cast<CallInst>(IncomingVal); | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2208 | BasicBlock *PredBB = PN->getIncomingBlock(I); | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2209 | // Make sure the phi value is indeed produced by the tail call. | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2210 | if (CI && CI->hasOneUse() && CI->getParent() == PredBB && | 
| Michael Kuperstein | f79af6f | 2016-09-08 00:48:37 +0000 | [diff] [blame] | 2211 | TLI->mayBeEmittedAsTailCall(CI) && | 
|  | 2212 | attributesPermitTailCall(F, CI, RetI, *TLI)) | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2213 | TailCallBBs.push_back(PredBB); | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2214 | } | 
|  | 2215 | } else { | 
|  | 2216 | SmallPtrSet<BasicBlock*, 4> VisitedBBs; | 
| Duncan P. N. Exon Smith | 6c99015 | 2014-07-21 17:06:51 +0000 | [diff] [blame] | 2217 | for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { | 
| David Blaikie | 70573dc | 2014-11-19 07:49:26 +0000 | [diff] [blame] | 2218 | if (!VisitedBBs.insert(*PI).second) | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2219 | continue; | 
|  | 2220 |  | 
| Duncan P. N. Exon Smith | 6c99015 | 2014-07-21 17:06:51 +0000 | [diff] [blame] | 2221 | BasicBlock::InstListType &InstList = (*PI)->getInstList(); | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2222 | BasicBlock::InstListType::reverse_iterator RI = InstList.rbegin(); | 
|  | 2223 | BasicBlock::InstListType::reverse_iterator RE = InstList.rend(); | 
| Cameron Zwarich | 74157ab | 2011-03-24 16:34:59 +0000 | [diff] [blame] | 2224 | do { ++RI; } while (RI != RE && isa<DbgInfoIntrinsic>(&*RI)); | 
|  | 2225 | if (RI == RE) | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2226 | continue; | 
| Cameron Zwarich | 74157ab | 2011-03-24 16:34:59 +0000 | [diff] [blame] | 2227 |  | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2228 | CallInst *CI = dyn_cast<CallInst>(&*RI); | 
| Michael Kuperstein | f79af6f | 2016-09-08 00:48:37 +0000 | [diff] [blame] | 2229 | if (CI && CI->use_empty() && TLI->mayBeEmittedAsTailCall(CI) && | 
|  | 2230 | attributesPermitTailCall(F, CI, RetI, *TLI)) | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2231 | TailCallBBs.push_back(*PI); | 
| Cameron Zwarich | 4649f17 | 2011-03-24 04:52:10 +0000 | [diff] [blame] | 2232 | } | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2233 | } | 
|  | 2234 |  | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2235 | bool Changed = false; | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2236 | for (auto const &TailCallBB : TailCallBBs) { | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2237 | // Make sure the call instruction is followed by an unconditional branch to | 
|  | 2238 | // the return block. | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2239 | BranchInst *BI = dyn_cast<BranchInst>(TailCallBB->getTerminator()); | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2240 | if (!BI || !BI->isUnconditional() || BI->getSuccessor(0) != BB) | 
|  | 2241 | continue; | 
|  | 2242 |  | 
| Kang Zhang | 038dd43 | 2019-08-02 03:09:07 +0000 | [diff] [blame] | 2243 | // Duplicate the return into TailCallBB. | 
|  | 2244 | (void)FoldReturnIntoUncondBranch(RetI, BB, TailCallBB); | 
| Hiroshi Yamauchi | 1b4e3de | 2020-04-03 10:40:26 -0700 | [diff] [blame] | 2245 | assert(!VerifyBFIUpdates || | 
|  | 2246 | BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB)); | 
|  | 2247 | BFI->setBlockFreq( | 
|  | 2248 | BB, | 
|  | 2249 | (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)).getFrequency()); | 
| Devang Patel | 8f606d7 | 2011-03-24 15:35:25 +0000 | [diff] [blame] | 2250 | ModifiedDT = Changed = true; | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2251 | ++NumRetsDup; | 
|  | 2252 | } | 
|  | 2253 |  | 
|  | 2254 | // If we eliminated all predecessors of the block, delete the block now. | 
| Evan Cheng | 64a223a | 2012-09-28 23:58:57 +0000 | [diff] [blame] | 2255 | if (Changed && !BB->hasAddressTaken() && pred_begin(BB) == pred_end(BB)) | 
| Cameron Zwarich | 0e331c0 | 2011-03-24 04:52:07 +0000 | [diff] [blame] | 2256 | BB->eraseFromParent(); | 
|  | 2257 |  | 
|  | 2258 | return Changed; | 
| Evan Cheng | 0663f23 | 2011-03-21 01:19:09 +0000 | [diff] [blame] | 2259 | } | 
|  | 2260 |  | 
| Chris Lattner | 728f902 | 2008-11-25 07:09:13 +0000 | [diff] [blame] | 2261 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 728f902 | 2008-11-25 07:09:13 +0000 | [diff] [blame] | 2262 | // Memory Optimization | 
|  | 2263 | //===----------------------------------------------------------------------===// | 
|  | 2264 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2265 | namespace { | 
|  | 2266 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 2267 | /// This is an extended version of TargetLowering::AddrMode | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2268 | /// which holds actual Value*'s for register values. | 
| Chandler Carruth | 95f83e0 | 2013-01-07 15:14:13 +0000 | [diff] [blame] | 2269 | struct ExtAddrMode : public TargetLowering::AddrMode { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2270 | Value *BaseReg = nullptr; | 
|  | 2271 | Value *ScaledReg = nullptr; | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 2272 | Value *OriginalValue = nullptr; | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 2273 | bool InBounds = true; | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 2274 |  | 
|  | 2275 | enum FieldName { | 
|  | 2276 | NoField        = 0x00, | 
|  | 2277 | BaseRegField   = 0x01, | 
|  | 2278 | BaseGVField    = 0x02, | 
|  | 2279 | BaseOffsField  = 0x04, | 
|  | 2280 | ScaledRegField = 0x08, | 
|  | 2281 | ScaleField     = 0x10, | 
|  | 2282 | MultipleFields = 0xff | 
|  | 2283 | }; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2284 |  | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 2285 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2286 | ExtAddrMode() = default; | 
|  | 2287 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2288 | void print(raw_ostream &OS) const; | 
|  | 2289 | void dump() const; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 2290 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 2291 | FieldName compare(const ExtAddrMode &other) { | 
|  | 2292 | // First check that the types are the same on each field, as differing types | 
|  | 2293 | // is something we can't cope with later on. | 
|  | 2294 | if (BaseReg && other.BaseReg && | 
|  | 2295 | BaseReg->getType() != other.BaseReg->getType()) | 
|  | 2296 | return MultipleFields; | 
|  | 2297 | if (BaseGV && other.BaseGV && | 
|  | 2298 | BaseGV->getType() != other.BaseGV->getType()) | 
|  | 2299 | return MultipleFields; | 
|  | 2300 | if (ScaledReg && other.ScaledReg && | 
|  | 2301 | ScaledReg->getType() != other.ScaledReg->getType()) | 
|  | 2302 | return MultipleFields; | 
|  | 2303 |  | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 2304 | // Conservatively reject 'inbounds' mismatches. | 
|  | 2305 | if (InBounds != other.InBounds) | 
|  | 2306 | return MultipleFields; | 
|  | 2307 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 2308 | // Check each field to see if it differs. | 
|  | 2309 | unsigned Result = NoField; | 
|  | 2310 | if (BaseReg != other.BaseReg) | 
|  | 2311 | Result |= BaseRegField; | 
|  | 2312 | if (BaseGV != other.BaseGV) | 
|  | 2313 | Result |= BaseGVField; | 
|  | 2314 | if (BaseOffs != other.BaseOffs) | 
|  | 2315 | Result |= BaseOffsField; | 
|  | 2316 | if (ScaledReg != other.ScaledReg) | 
|  | 2317 | Result |= ScaledRegField; | 
|  | 2318 | // Don't count 0 as being a different scale, because that actually means | 
|  | 2319 | // unscaled (which will already be counted by having no ScaledReg). | 
|  | 2320 | if (Scale && other.Scale && Scale != other.Scale) | 
|  | 2321 | Result |= ScaleField; | 
|  | 2322 |  | 
|  | 2323 | if (countPopulation(Result) > 1) | 
|  | 2324 | return MultipleFields; | 
|  | 2325 | else | 
|  | 2326 | return static_cast<FieldName>(Result); | 
|  | 2327 | } | 
|  | 2328 |  | 
| John Brawn | 4b47648 | 2017-11-27 11:29:15 +0000 | [diff] [blame] | 2329 | // An AddrMode is trivial if it involves no calculation i.e. it is just a base | 
|  | 2330 | // with no offset. | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 2331 | bool isTrivial() { | 
| John Brawn | 4b47648 | 2017-11-27 11:29:15 +0000 | [diff] [blame] | 2332 | // An AddrMode is (BaseGV + BaseReg + BaseOffs + ScaleReg * Scale) so it is | 
|  | 2333 | // trivial if at most one of these terms is nonzero, except that BaseGV and | 
|  | 2334 | // BaseReg both being zero actually means a null pointer value, which we | 
|  | 2335 | // consider to be 'non-zero' here. | 
|  | 2336 | return !BaseOffs && !Scale && !(BaseGV && BaseReg); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2337 | } | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 2338 |  | 
|  | 2339 | Value *GetFieldAsValue(FieldName Field, Type *IntPtrTy) { | 
|  | 2340 | switch (Field) { | 
|  | 2341 | default: | 
|  | 2342 | return nullptr; | 
|  | 2343 | case BaseRegField: | 
|  | 2344 | return BaseReg; | 
|  | 2345 | case BaseGVField: | 
|  | 2346 | return BaseGV; | 
|  | 2347 | case ScaledRegField: | 
|  | 2348 | return ScaledReg; | 
|  | 2349 | case BaseOffsField: | 
|  | 2350 | return ConstantInt::get(IntPtrTy, BaseOffs); | 
|  | 2351 | } | 
|  | 2352 | } | 
|  | 2353 |  | 
|  | 2354 | void SetCombinedField(FieldName Field, Value *V, | 
|  | 2355 | const SmallVectorImpl<ExtAddrMode> &AddrModes) { | 
|  | 2356 | switch (Field) { | 
|  | 2357 | default: | 
|  | 2358 | llvm_unreachable("Unhandled fields are expected to be rejected earlier"); | 
|  | 2359 | break; | 
|  | 2360 | case ExtAddrMode::BaseRegField: | 
|  | 2361 | BaseReg = V; | 
|  | 2362 | break; | 
|  | 2363 | case ExtAddrMode::BaseGVField: | 
|  | 2364 | // A combined BaseGV is an Instruction, not a GlobalValue, so it goes | 
|  | 2365 | // in the BaseReg field. | 
|  | 2366 | assert(BaseReg == nullptr); | 
|  | 2367 | BaseReg = V; | 
|  | 2368 | BaseGV = nullptr; | 
|  | 2369 | break; | 
|  | 2370 | case ExtAddrMode::ScaledRegField: | 
|  | 2371 | ScaledReg = V; | 
|  | 2372 | // If we have a mix of scaled and unscaled addrmodes then we want scale | 
|  | 2373 | // to be the scale and not zero. | 
|  | 2374 | if (!Scale) | 
|  | 2375 | for (const ExtAddrMode &AM : AddrModes) | 
|  | 2376 | if (AM.Scale) { | 
|  | 2377 | Scale = AM.Scale; | 
|  | 2378 | break; | 
|  | 2379 | } | 
|  | 2380 | break; | 
|  | 2381 | case ExtAddrMode::BaseOffsField: | 
|  | 2382 | // The offset is no longer a constant, so it goes in ScaledReg with a | 
|  | 2383 | // scale of 1. | 
|  | 2384 | assert(ScaledReg == nullptr); | 
|  | 2385 | ScaledReg = V; | 
|  | 2386 | Scale = 1; | 
|  | 2387 | BaseOffs = 0; | 
|  | 2388 | break; | 
|  | 2389 | } | 
|  | 2390 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2391 | }; | 
|  | 2392 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2393 | } // end anonymous namespace | 
|  | 2394 |  | 
| Eli Friedman | c1f1f85 | 2013-09-10 23:09:24 +0000 | [diff] [blame] | 2395 | #ifndef NDEBUG | 
|  | 2396 | static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) { | 
|  | 2397 | AM.print(OS); | 
|  | 2398 | return OS; | 
|  | 2399 | } | 
|  | 2400 | #endif | 
|  | 2401 |  | 
| Aaron Ballman | 615eb47 | 2017-10-15 14:32:27 +0000 | [diff] [blame] | 2402 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2403 | void ExtAddrMode::print(raw_ostream &OS) const { | 
|  | 2404 | bool NeedPlus = false; | 
|  | 2405 | OS << "["; | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 2406 | if (InBounds) | 
|  | 2407 | OS << "inbounds "; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2408 | if (BaseGV) { | 
|  | 2409 | OS << (NeedPlus ? " + " : "") | 
|  | 2410 | << "GV:"; | 
| Chandler Carruth | d48cdbf | 2014-01-09 02:29:41 +0000 | [diff] [blame] | 2411 | BaseGV->printAsOperand(OS, /*PrintType=*/false); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2412 | NeedPlus = true; | 
|  | 2413 | } | 
|  | 2414 |  | 
| Richard Trieu | c0f9121 | 2014-05-30 03:15:17 +0000 | [diff] [blame] | 2415 | if (BaseOffs) { | 
|  | 2416 | OS << (NeedPlus ? " + " : "") | 
|  | 2417 | << BaseOffs; | 
|  | 2418 | NeedPlus = true; | 
|  | 2419 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2420 |  | 
|  | 2421 | if (BaseReg) { | 
|  | 2422 | OS << (NeedPlus ? " + " : "") | 
|  | 2423 | << "Base:"; | 
| Chandler Carruth | d48cdbf | 2014-01-09 02:29:41 +0000 | [diff] [blame] | 2424 | BaseReg->printAsOperand(OS, /*PrintType=*/false); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2425 | NeedPlus = true; | 
|  | 2426 | } | 
|  | 2427 | if (Scale) { | 
|  | 2428 | OS << (NeedPlus ? " + " : "") | 
|  | 2429 | << Scale << "*"; | 
| Chandler Carruth | d48cdbf | 2014-01-09 02:29:41 +0000 | [diff] [blame] | 2430 | ScaledReg->printAsOperand(OS, /*PrintType=*/false); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2431 | } | 
|  | 2432 |  | 
|  | 2433 | OS << ']'; | 
|  | 2434 | } | 
|  | 2435 |  | 
| Yaron Keren | eb2a254 | 2016-01-29 20:50:44 +0000 | [diff] [blame] | 2436 | LLVM_DUMP_METHOD void ExtAddrMode::dump() const { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2437 | print(dbgs()); | 
|  | 2438 | dbgs() << '\n'; | 
|  | 2439 | } | 
|  | 2440 | #endif | 
|  | 2441 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2442 | namespace { | 
|  | 2443 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2444 | /// This class provides transaction based operation on the IR. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2445 | /// Every change made through this class is recorded in the internal state and | 
|  | 2446 | /// can be undone (rollback) until commit is called. | 
|  | 2447 | class TypePromotionTransaction { | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2448 | /// This represents the common interface of the individual transaction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2449 | /// Each class implements the logic for doing one specific modification on | 
|  | 2450 | /// the IR via the TypePromotionTransaction. | 
|  | 2451 | class TypePromotionAction { | 
|  | 2452 | protected: | 
|  | 2453 | /// The Instruction modified. | 
|  | 2454 | Instruction *Inst; | 
|  | 2455 |  | 
|  | 2456 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2457 | /// Constructor of the action. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2458 | /// The constructor performs the related action on the IR. | 
|  | 2459 | TypePromotionAction(Instruction *Inst) : Inst(Inst) {} | 
|  | 2460 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2461 | virtual ~TypePromotionAction() = default; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2462 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2463 | /// Undo the modification done by this action. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2464 | /// When this method is called, the IR must be in the same state as it was | 
|  | 2465 | /// before this action was applied. | 
|  | 2466 | /// \pre Undoing the action works if and only if the IR is in the exact same | 
|  | 2467 | /// state as it was directly after this action was applied. | 
|  | 2468 | virtual void undo() = 0; | 
|  | 2469 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2470 | /// Advocate every change made by this action. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2471 | /// When the results on the IR of the action are to be kept, it is important | 
|  | 2472 | /// to call this function, otherwise hidden information may be kept forever. | 
|  | 2473 | virtual void commit() { | 
|  | 2474 | // Nothing to be done, this action is not doing anything. | 
|  | 2475 | } | 
|  | 2476 | }; | 
|  | 2477 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2478 | /// Utility to remember the position of an instruction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2479 | class InsertionHandler { | 
|  | 2480 | /// Position of an instruction. | 
|  | 2481 | /// Either an instruction: | 
|  | 2482 | /// - Is the first in a basic block: BB is used. | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 2483 | /// - Has a previous instruction: PrevInst is used. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2484 | union { | 
|  | 2485 | Instruction *PrevInst; | 
|  | 2486 | BasicBlock *BB; | 
|  | 2487 | } Point; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2488 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2489 | /// Remember whether or not the instruction had a previous instruction. | 
|  | 2490 | bool HasPrevInstruction; | 
|  | 2491 |  | 
|  | 2492 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2493 | /// Record the position of \p Inst. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2494 | InsertionHandler(Instruction *Inst) { | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 2495 | BasicBlock::iterator It = Inst->getIterator(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2496 | HasPrevInstruction = (It != (Inst->getParent()->begin())); | 
|  | 2497 | if (HasPrevInstruction) | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 2498 | Point.PrevInst = &*--It; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2499 | else | 
|  | 2500 | Point.BB = Inst->getParent(); | 
|  | 2501 | } | 
|  | 2502 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2503 | /// Insert \p Inst at the recorded position. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2504 | void insert(Instruction *Inst) { | 
|  | 2505 | if (HasPrevInstruction) { | 
|  | 2506 | if (Inst->getParent()) | 
|  | 2507 | Inst->removeFromParent(); | 
|  | 2508 | Inst->insertAfter(Point.PrevInst); | 
|  | 2509 | } else { | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 2510 | Instruction *Position = &*Point.BB->getFirstInsertionPt(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2511 | if (Inst->getParent()) | 
|  | 2512 | Inst->moveBefore(Position); | 
|  | 2513 | else | 
|  | 2514 | Inst->insertBefore(Position); | 
|  | 2515 | } | 
|  | 2516 | } | 
|  | 2517 | }; | 
|  | 2518 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2519 | /// Move an instruction before another. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2520 | class InstructionMoveBefore : public TypePromotionAction { | 
|  | 2521 | /// Original position of the instruction. | 
|  | 2522 | InsertionHandler Position; | 
|  | 2523 |  | 
|  | 2524 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2525 | /// Move \p Inst before \p Before. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2526 | InstructionMoveBefore(Instruction *Inst, Instruction *Before) | 
|  | 2527 | : TypePromotionAction(Inst), Position(Inst) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2528 | LLVM_DEBUG(dbgs() << "Do: move: " << *Inst << "\nbefore: " << *Before | 
|  | 2529 | << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2530 | Inst->moveBefore(Before); | 
|  | 2531 | } | 
|  | 2532 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2533 | /// Move the instruction back to its original position. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2534 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2535 | LLVM_DEBUG(dbgs() << "Undo: moveBefore: " << *Inst << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2536 | Position.insert(Inst); | 
|  | 2537 | } | 
|  | 2538 | }; | 
|  | 2539 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2540 | /// Set the operand of an instruction with a new value. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2541 | class OperandSetter : public TypePromotionAction { | 
|  | 2542 | /// Original operand of the instruction. | 
|  | 2543 | Value *Origin; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2544 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2545 | /// Index of the modified instruction. | 
|  | 2546 | unsigned Idx; | 
|  | 2547 |  | 
|  | 2548 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2549 | /// Set \p Idx operand of \p Inst with \p NewVal. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2550 | OperandSetter(Instruction *Inst, unsigned Idx, Value *NewVal) | 
|  | 2551 | : TypePromotionAction(Inst), Idx(Idx) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2552 | LLVM_DEBUG(dbgs() << "Do: setOperand: " << Idx << "\n" | 
|  | 2553 | << "for:" << *Inst << "\n" | 
|  | 2554 | << "with:" << *NewVal << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2555 | Origin = Inst->getOperand(Idx); | 
|  | 2556 | Inst->setOperand(Idx, NewVal); | 
|  | 2557 | } | 
|  | 2558 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2559 | /// Restore the original value of the instruction. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2560 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2561 | LLVM_DEBUG(dbgs() << "Undo: setOperand:" << Idx << "\n" | 
|  | 2562 | << "for: " << *Inst << "\n" | 
|  | 2563 | << "with: " << *Origin << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2564 | Inst->setOperand(Idx, Origin); | 
|  | 2565 | } | 
|  | 2566 | }; | 
|  | 2567 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2568 | /// Hide the operands of an instruction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2569 | /// Do as if this instruction was not using any of its operands. | 
|  | 2570 | class OperandsHider : public TypePromotionAction { | 
|  | 2571 | /// The list of original operands. | 
|  | 2572 | SmallVector<Value *, 4> OriginalValues; | 
|  | 2573 |  | 
|  | 2574 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2575 | /// Remove \p Inst from the uses of the operands of \p Inst. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2576 | OperandsHider(Instruction *Inst) : TypePromotionAction(Inst) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2577 | LLVM_DEBUG(dbgs() << "Do: OperandsHider: " << *Inst << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2578 | unsigned NumOpnds = Inst->getNumOperands(); | 
|  | 2579 | OriginalValues.reserve(NumOpnds); | 
|  | 2580 | for (unsigned It = 0; It < NumOpnds; ++It) { | 
|  | 2581 | // Save the current operand. | 
|  | 2582 | Value *Val = Inst->getOperand(It); | 
|  | 2583 | OriginalValues.push_back(Val); | 
|  | 2584 | // Set a dummy one. | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 2585 | // We could use OperandSetter here, but that would imply an overhead | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2586 | // that we are not willing to pay. | 
|  | 2587 | Inst->setOperand(It, UndefValue::get(Val->getType())); | 
|  | 2588 | } | 
|  | 2589 | } | 
|  | 2590 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2591 | /// Restore the original list of uses. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2592 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2593 | LLVM_DEBUG(dbgs() << "Undo: OperandsHider: " << *Inst << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2594 | for (unsigned It = 0, EndIt = OriginalValues.size(); It != EndIt; ++It) | 
|  | 2595 | Inst->setOperand(It, OriginalValues[It]); | 
|  | 2596 | } | 
|  | 2597 | }; | 
|  | 2598 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2599 | /// Build a truncate instruction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2600 | class TruncBuilder : public TypePromotionAction { | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2601 | Value *Val; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2602 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2603 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2604 | /// Build a truncate instruction of \p Opnd producing a \p Ty | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2605 | /// result. | 
|  | 2606 | /// trunc Opnd to Ty. | 
|  | 2607 | TruncBuilder(Instruction *Opnd, Type *Ty) : TypePromotionAction(Opnd) { | 
|  | 2608 | IRBuilder<> Builder(Opnd); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2609 | Val = Builder.CreateTrunc(Opnd, Ty, "promoted"); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2610 | LLVM_DEBUG(dbgs() << "Do: TruncBuilder: " << *Val << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2611 | } | 
|  | 2612 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2613 | /// Get the built value. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2614 | Value *getBuiltValue() { return Val; } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2615 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2616 | /// Remove the built instruction. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2617 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2618 | LLVM_DEBUG(dbgs() << "Undo: TruncBuilder: " << *Val << "\n"); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2619 | if (Instruction *IVal = dyn_cast<Instruction>(Val)) | 
|  | 2620 | IVal->eraseFromParent(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2621 | } | 
|  | 2622 | }; | 
|  | 2623 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2624 | /// Build a sign extension instruction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2625 | class SExtBuilder : public TypePromotionAction { | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2626 | Value *Val; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2627 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2628 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2629 | /// Build a sign extension instruction of \p Opnd producing a \p Ty | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2630 | /// result. | 
|  | 2631 | /// sext Opnd to Ty. | 
|  | 2632 | SExtBuilder(Instruction *InsertPt, Value *Opnd, Type *Ty) | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2633 | : TypePromotionAction(InsertPt) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2634 | IRBuilder<> Builder(InsertPt); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2635 | Val = Builder.CreateSExt(Opnd, Ty, "promoted"); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2636 | LLVM_DEBUG(dbgs() << "Do: SExtBuilder: " << *Val << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2637 | } | 
|  | 2638 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2639 | /// Get the built value. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2640 | Value *getBuiltValue() { return Val; } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2641 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2642 | /// Remove the built instruction. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2643 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2644 | LLVM_DEBUG(dbgs() << "Undo: SExtBuilder: " << *Val << "\n"); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2645 | if (Instruction *IVal = dyn_cast<Instruction>(Val)) | 
|  | 2646 | IVal->eraseFromParent(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2647 | } | 
|  | 2648 | }; | 
|  | 2649 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2650 | /// Build a zero extension instruction. | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2651 | class ZExtBuilder : public TypePromotionAction { | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2652 | Value *Val; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2653 |  | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2654 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2655 | /// Build a zero extension instruction of \p Opnd producing a \p Ty | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2656 | /// result. | 
|  | 2657 | /// zext Opnd to Ty. | 
|  | 2658 | ZExtBuilder(Instruction *InsertPt, Value *Opnd, Type *Ty) | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2659 | : TypePromotionAction(InsertPt) { | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2660 | IRBuilder<> Builder(InsertPt); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2661 | Val = Builder.CreateZExt(Opnd, Ty, "promoted"); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2662 | LLVM_DEBUG(dbgs() << "Do: ZExtBuilder: " << *Val << "\n"); | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2663 | } | 
|  | 2664 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2665 | /// Get the built value. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2666 | Value *getBuiltValue() { return Val; } | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2667 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2668 | /// Remove the built instruction. | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2669 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2670 | LLVM_DEBUG(dbgs() << "Undo: ZExtBuilder: " << *Val << "\n"); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2671 | if (Instruction *IVal = dyn_cast<Instruction>(Val)) | 
|  | 2672 | IVal->eraseFromParent(); | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2673 | } | 
|  | 2674 | }; | 
|  | 2675 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2676 | /// Mutate an instruction to another type. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2677 | class TypeMutator : public TypePromotionAction { | 
|  | 2678 | /// Record the original type. | 
|  | 2679 | Type *OrigTy; | 
|  | 2680 |  | 
|  | 2681 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2682 | /// Mutate the type of \p Inst into \p NewTy. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2683 | TypeMutator(Instruction *Inst, Type *NewTy) | 
|  | 2684 | : TypePromotionAction(Inst), OrigTy(Inst->getType()) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2685 | LLVM_DEBUG(dbgs() << "Do: MutateType: " << *Inst << " with " << *NewTy | 
|  | 2686 | << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2687 | Inst->mutateType(NewTy); | 
|  | 2688 | } | 
|  | 2689 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2690 | /// Mutate the instruction back to its original type. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2691 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2692 | LLVM_DEBUG(dbgs() << "Undo: MutateType: " << *Inst << " with " << *OrigTy | 
|  | 2693 | << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2694 | Inst->mutateType(OrigTy); | 
|  | 2695 | } | 
|  | 2696 | }; | 
|  | 2697 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2698 | /// Replace the uses of an instruction by another instruction. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2699 | class UsesReplacer : public TypePromotionAction { | 
|  | 2700 | /// Helper structure to keep track of the replaced uses. | 
|  | 2701 | struct InstructionAndIdx { | 
|  | 2702 | /// The instruction using the instruction. | 
|  | 2703 | Instruction *Inst; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2704 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2705 | /// The index where this instruction is used for Inst. | 
|  | 2706 | unsigned Idx; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2707 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2708 | InstructionAndIdx(Instruction *Inst, unsigned Idx) | 
|  | 2709 | : Inst(Inst), Idx(Idx) {} | 
|  | 2710 | }; | 
|  | 2711 |  | 
|  | 2712 | /// Keep track of the original uses (pair Instruction, Index). | 
|  | 2713 | SmallVector<InstructionAndIdx, 4> OriginalUses; | 
| Wolfgang Pieb | ac874c4 | 2018-12-11 21:13:53 +0000 | [diff] [blame] | 2714 | /// Keep track of the debug users. | 
|  | 2715 | SmallVector<DbgValueInst *, 1> DbgValues; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2716 |  | 
|  | 2717 | using use_iterator = SmallVectorImpl<InstructionAndIdx>::iterator; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2718 |  | 
|  | 2719 | public: | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2720 | /// Replace all the use of \p Inst by \p New. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2721 | UsesReplacer(Instruction *Inst, Value *New) : TypePromotionAction(Inst) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2722 | LLVM_DEBUG(dbgs() << "Do: UsersReplacer: " << *Inst << " with " << *New | 
|  | 2723 | << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2724 | // Record the original uses. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 2725 | for (Use &U : Inst->uses()) { | 
|  | 2726 | Instruction *UserI = cast<Instruction>(U.getUser()); | 
|  | 2727 | OriginalUses.push_back(InstructionAndIdx(UserI, U.getOperandNo())); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2728 | } | 
| Wolfgang Pieb | ac874c4 | 2018-12-11 21:13:53 +0000 | [diff] [blame] | 2729 | // Record the debug uses separately. They are not in the instruction's | 
|  | 2730 | // use list, but they are replaced by RAUW. | 
|  | 2731 | findDbgValues(DbgValues, Inst); | 
|  | 2732 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2733 | // Now, we can replace the uses. | 
|  | 2734 | Inst->replaceAllUsesWith(New); | 
|  | 2735 | } | 
|  | 2736 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2737 | /// Reassign the original uses of Inst to Inst. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2738 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2739 | LLVM_DEBUG(dbgs() << "Undo: UsersReplacer: " << *Inst << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2740 | for (use_iterator UseIt = OriginalUses.begin(), | 
|  | 2741 | EndIt = OriginalUses.end(); | 
|  | 2742 | UseIt != EndIt; ++UseIt) { | 
|  | 2743 | UseIt->Inst->setOperand(UseIt->Idx, Inst); | 
|  | 2744 | } | 
| Wolfgang Pieb | ac874c4 | 2018-12-11 21:13:53 +0000 | [diff] [blame] | 2745 | // RAUW has replaced all original uses with references to the new value, | 
|  | 2746 | // including the debug uses. Since we are undoing the replacements, | 
|  | 2747 | // the original debug uses must also be reinstated to maintain the | 
|  | 2748 | // correctness and utility of debug value instructions. | 
|  | 2749 | for (auto *DVI: DbgValues) { | 
|  | 2750 | LLVMContext &Ctx = Inst->getType()->getContext(); | 
|  | 2751 | auto *MV = MetadataAsValue::get(Ctx, ValueAsMetadata::get(Inst)); | 
|  | 2752 | DVI->setOperand(0, MV); | 
|  | 2753 | } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2754 | } | 
|  | 2755 | }; | 
|  | 2756 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2757 | /// Remove an instruction from the IR. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2758 | class InstructionRemover : public TypePromotionAction { | 
|  | 2759 | /// Original position of the instruction. | 
|  | 2760 | InsertionHandler Inserter; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2761 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2762 | /// Helper structure to hide all the link to the instruction. In other | 
|  | 2763 | /// words, this helps to do as if the instruction was removed. | 
|  | 2764 | OperandsHider Hider; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2765 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2766 | /// Keep track of the uses replaced, if any. | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2767 | UsesReplacer *Replacer = nullptr; | 
|  | 2768 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2769 | /// Keep track of instructions removed. | 
|  | 2770 | SetOfInstrs &RemovedInsts; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2771 |  | 
|  | 2772 | public: | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 2773 | /// Remove all reference of \p Inst and optionally replace all its | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2774 | /// uses with New. | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2775 | /// \p RemovedInsts Keep track of the instructions removed by this Action. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 2776 | /// \pre If !Inst->use_empty(), then New != nullptr | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2777 | InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts, | 
|  | 2778 | Value *New = nullptr) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2779 | : TypePromotionAction(Inst), Inserter(Inst), Hider(Inst), | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2780 | RemovedInsts(RemovedInsts) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2781 | if (New) | 
|  | 2782 | Replacer = new UsesReplacer(Inst, New); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2783 | LLVM_DEBUG(dbgs() << "Do: InstructionRemover: " << *Inst << "\n"); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2784 | RemovedInsts.insert(Inst); | 
|  | 2785 | /// The instructions removed here will be freed after completing | 
|  | 2786 | /// optimizeBlock() for all blocks as we need to keep track of the | 
|  | 2787 | /// removed instructions during promotion. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2788 | Inst->removeFromParent(); | 
|  | 2789 | } | 
|  | 2790 |  | 
| Alexander Kornienko | f817c1c | 2015-04-11 02:11:45 +0000 | [diff] [blame] | 2791 | ~InstructionRemover() override { delete Replacer; } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2792 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2793 | /// Resurrect the instruction and reassign it to the proper uses if | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2794 | /// new value was provided when build this action. | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 2795 | void undo() override { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 2796 | LLVM_DEBUG(dbgs() << "Undo: InstructionRemover: " << *Inst << "\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2797 | Inserter.insert(Inst); | 
|  | 2798 | if (Replacer) | 
|  | 2799 | Replacer->undo(); | 
|  | 2800 | Hider.undo(); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2801 | RemovedInsts.erase(Inst); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2802 | } | 
|  | 2803 | }; | 
|  | 2804 |  | 
|  | 2805 | public: | 
|  | 2806 | /// Restoration point. | 
|  | 2807 | /// The restoration point is a pointer to an action instead of an iterator | 
|  | 2808 | /// because the iterator may be invalidated but not the pointer. | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2809 | using ConstRestorationPt = const TypePromotionAction *; | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2810 |  | 
|  | 2811 | TypePromotionTransaction(SetOfInstrs &RemovedInsts) | 
|  | 2812 | : RemovedInsts(RemovedInsts) {} | 
|  | 2813 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2814 | /// Advocate every changes made in that transaction. | 
|  | 2815 | void commit(); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2816 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2817 | /// Undo all the changes made after the given point. | 
|  | 2818 | void rollback(ConstRestorationPt Point); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2819 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2820 | /// Get the current restoration point. | 
|  | 2821 | ConstRestorationPt getRestorationPoint() const; | 
|  | 2822 |  | 
|  | 2823 | /// \name API for IR modification with state keeping to support rollback. | 
|  | 2824 | /// @{ | 
|  | 2825 | /// Same as Instruction::setOperand. | 
|  | 2826 | void setOperand(Instruction *Inst, unsigned Idx, Value *NewVal); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2827 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2828 | /// Same as Instruction::eraseFromParent. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 2829 | void eraseInstruction(Instruction *Inst, Value *NewVal = nullptr); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2830 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2831 | /// Same as Value::replaceAllUsesWith. | 
|  | 2832 | void replaceAllUsesWith(Instruction *Inst, Value *New); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2833 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2834 | /// Same as Value::mutateType. | 
|  | 2835 | void mutateType(Instruction *Inst, Type *NewTy); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2836 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2837 | /// Same as IRBuilder::createTrunc. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2838 | Value *createTrunc(Instruction *Opnd, Type *Ty); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2839 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2840 | /// Same as IRBuilder::createSExt. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2841 | Value *createSExt(Instruction *Inst, Value *Opnd, Type *Ty); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2842 |  | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2843 | /// Same as IRBuilder::createZExt. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2844 | Value *createZExt(Instruction *Inst, Value *Opnd, Type *Ty); | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2845 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2846 | /// Same as Instruction::moveBefore. | 
|  | 2847 | void moveBefore(Instruction *Inst, Instruction *Before); | 
|  | 2848 | /// @} | 
|  | 2849 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2850 | private: | 
|  | 2851 | /// The ordered list of actions made so far. | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2852 | SmallVector<std::unique_ptr<TypePromotionAction>, 16> Actions; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2853 |  | 
|  | 2854 | using CommitPt = SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator; | 
|  | 2855 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 2856 | SetOfInstrs &RemovedInsts; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2857 | }; | 
|  | 2858 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2859 | } // end anonymous namespace | 
|  | 2860 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2861 | void TypePromotionTransaction::setOperand(Instruction *Inst, unsigned Idx, | 
|  | 2862 | Value *NewVal) { | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 2863 | Actions.push_back(std::make_unique<TypePromotionTransaction::OperandSetter>( | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2864 | Inst, Idx, NewVal)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2865 | } | 
|  | 2866 |  | 
|  | 2867 | void TypePromotionTransaction::eraseInstruction(Instruction *Inst, | 
|  | 2868 | Value *NewVal) { | 
|  | 2869 | Actions.push_back( | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 2870 | std::make_unique<TypePromotionTransaction::InstructionRemover>( | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2871 | Inst, RemovedInsts, NewVal)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2872 | } | 
|  | 2873 |  | 
|  | 2874 | void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst, | 
|  | 2875 | Value *New) { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2876 | Actions.push_back( | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 2877 | std::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2878 | } | 
|  | 2879 |  | 
|  | 2880 | void TypePromotionTransaction::mutateType(Instruction *Inst, Type *NewTy) { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2881 | Actions.push_back( | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 2882 | std::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2883 | } | 
|  | 2884 |  | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2885 | Value *TypePromotionTransaction::createTrunc(Instruction *Opnd, | 
|  | 2886 | Type *Ty) { | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2887 | std::unique_ptr<TruncBuilder> Ptr(new TruncBuilder(Opnd, Ty)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2888 | Value *Val = Ptr->getBuiltValue(); | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2889 | Actions.push_back(std::move(Ptr)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2890 | return Val; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2891 | } | 
|  | 2892 |  | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2893 | Value *TypePromotionTransaction::createSExt(Instruction *Inst, | 
|  | 2894 | Value *Opnd, Type *Ty) { | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2895 | std::unique_ptr<SExtBuilder> Ptr(new SExtBuilder(Inst, Opnd, Ty)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2896 | Value *Val = Ptr->getBuiltValue(); | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2897 | Actions.push_back(std::move(Ptr)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2898 | return Val; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2899 | } | 
|  | 2900 |  | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2901 | Value *TypePromotionTransaction::createZExt(Instruction *Inst, | 
|  | 2902 | Value *Opnd, Type *Ty) { | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2903 | std::unique_ptr<ZExtBuilder> Ptr(new ZExtBuilder(Inst, Opnd, Ty)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2904 | Value *Val = Ptr->getBuiltValue(); | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2905 | Actions.push_back(std::move(Ptr)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 2906 | return Val; | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 2907 | } | 
|  | 2908 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2909 | void TypePromotionTransaction::moveBefore(Instruction *Inst, | 
|  | 2910 | Instruction *Before) { | 
|  | 2911 | Actions.push_back( | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 2912 | std::make_unique<TypePromotionTransaction::InstructionMoveBefore>( | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2913 | Inst, Before)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2914 | } | 
|  | 2915 |  | 
|  | 2916 | TypePromotionTransaction::ConstRestorationPt | 
|  | 2917 | TypePromotionTransaction::getRestorationPoint() const { | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2918 | return !Actions.empty() ? Actions.back().get() : nullptr; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2919 | } | 
|  | 2920 |  | 
|  | 2921 | void TypePromotionTransaction::commit() { | 
|  | 2922 | for (CommitPt It = Actions.begin(), EndIt = Actions.end(); It != EndIt; | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2923 | ++It) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2924 | (*It)->commit(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2925 | Actions.clear(); | 
|  | 2926 | } | 
|  | 2927 |  | 
|  | 2928 | void TypePromotionTransaction::rollback( | 
|  | 2929 | TypePromotionTransaction::ConstRestorationPt Point) { | 
| David Blaikie | 7620b31 | 2014-04-15 06:17:44 +0000 | [diff] [blame] | 2930 | while (!Actions.empty() && Point != Actions.back().get()) { | 
|  | 2931 | std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2932 | Curr->undo(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2933 | } | 
|  | 2934 | } | 
|  | 2935 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2936 | namespace { | 
|  | 2937 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 2938 | /// A helper class for matching addressing modes. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2939 | /// | 
|  | 2940 | /// This encapsulates the logic for matching the target-legal addressing modes. | 
|  | 2941 | class AddressingModeMatcher { | 
|  | 2942 | SmallVectorImpl<Instruction*> &AddrModeInsts; | 
|  | 2943 | const TargetLowering &TLI; | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 2944 | const TargetRegisterInfo &TRI; | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 2945 | const DataLayout &DL; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2946 |  | 
|  | 2947 | /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and | 
|  | 2948 | /// the memory instruction that we're computing this address for. | 
|  | 2949 | Type *AccessTy; | 
| Matt Arsenault | f72b49b | 2015-06-04 16:17:38 +0000 | [diff] [blame] | 2950 | unsigned AddrSpace; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2951 | Instruction *MemoryInst; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 2952 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 2953 | /// This is the addressing mode that we're building up. This is | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2954 | /// part of the return value of this addressing mode matching stuff. | 
|  | 2955 | ExtAddrMode &AddrMode; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 2956 |  | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 2957 | /// The instructions inserted by other CodeGenPrepare optimizations. | 
|  | 2958 | const SetOfInstrs &InsertedInsts; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2959 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2960 | /// A map from the instructions to their type before promotion. | 
|  | 2961 | InstrToOrigTy &PromotedInsts; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2962 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2963 | /// The ongoing transaction where every action should be registered. | 
|  | 2964 | TypePromotionTransaction &TPT; | 
|  | 2965 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 2966 | // A GEP which has too large offset to be folded into the addressing mode. | 
|  | 2967 | std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP; | 
|  | 2968 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 2969 | /// This is set to true when we should not do profitability checks. | 
|  | 2970 | /// When true, IsProfitableToFoldIntoAddressingMode always returns true. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2971 | bool IgnoreProfitability; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 2972 |  | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 2973 | /// True if we are optimizing for size. | 
|  | 2974 | bool OptSize; | 
|  | 2975 |  | 
|  | 2976 | ProfileSummaryInfo *PSI; | 
|  | 2977 | BlockFrequencyInfo *BFI; | 
|  | 2978 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 2979 | AddressingModeMatcher( | 
|  | 2980 | SmallVectorImpl<Instruction *> &AMI, const TargetLowering &TLI, | 
|  | 2981 | const TargetRegisterInfo &TRI, Type *AT, unsigned AS, Instruction *MI, | 
|  | 2982 | ExtAddrMode &AM, const SetOfInstrs &InsertedInsts, | 
|  | 2983 | InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 2984 | std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP, | 
|  | 2985 | bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 2986 | : AddrModeInsts(AMI), TLI(TLI), TRI(TRI), | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 2987 | DL(MI->getModule()->getDataLayout()), AccessTy(AT), AddrSpace(AS), | 
|  | 2988 | MemoryInst(MI), AddrMode(AM), InsertedInsts(InsertedInsts), | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 2989 | PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP), | 
|  | 2990 | OptSize(OptSize), PSI(PSI), BFI(BFI) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2991 | IgnoreProfitability = false; | 
|  | 2992 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 2993 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 2994 | public: | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 2995 | /// Find the maximal addressing mode that a load/store of V can fold, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 2996 | /// give an access type of AccessTy.  This returns a list of involved | 
|  | 2997 | /// instructions in AddrModeInsts. | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 2998 | /// \p InsertedInsts The instructions inserted by other CodeGenPrepare | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 2999 | /// optimizations. | 
|  | 3000 | /// \p PromotedInsts maps the instructions to their type before promotion. | 
|  | 3001 | /// \p The ongoing transaction where every action should be registered. | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 3002 | static ExtAddrMode | 
|  | 3003 | Match(Value *V, Type *AccessTy, unsigned AS, Instruction *MemoryInst, | 
|  | 3004 | SmallVectorImpl<Instruction *> &AddrModeInsts, | 
|  | 3005 | const TargetLowering &TLI, const TargetRegisterInfo &TRI, | 
|  | 3006 | const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts, | 
|  | 3007 | TypePromotionTransaction &TPT, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 3008 | std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP, | 
|  | 3009 | bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3010 | ExtAddrMode Result; | 
|  | 3011 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 3012 | bool Success = AddressingModeMatcher(AddrModeInsts, TLI, TRI, AccessTy, AS, | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 3013 | MemoryInst, Result, InsertedInsts, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 3014 | PromotedInsts, TPT, LargeOffsetGEP, | 
|  | 3015 | OptSize, PSI, BFI) | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 3016 | .matchAddr(V, 0); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3017 | (void)Success; assert(Success && "Couldn't select *anything*?"); | 
|  | 3018 | return Result; | 
|  | 3019 | } | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 3020 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3021 | private: | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 3022 | bool matchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth); | 
| Fangrui Song | cb0bab8 | 2018-07-16 18:51:40 +0000 | [diff] [blame] | 3023 | bool matchAddr(Value *Addr, unsigned Depth); | 
|  | 3024 | bool matchOperationAddr(User *AddrInst, unsigned Opcode, unsigned Depth, | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 3025 | bool *MovedAway = nullptr); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 3026 | bool isProfitableToFoldIntoAddressingMode(Instruction *I, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3027 | ExtAddrMode &AMBefore, | 
|  | 3028 | ExtAddrMode &AMAfter); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 3029 | bool valueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2); | 
|  | 3030 | bool isPromotionProfitable(unsigned NewCost, unsigned OldCost, | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 3031 | Value *PromotedOperand) const; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3032 | }; | 
|  | 3033 |  | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3034 | class PhiNodeSet; | 
|  | 3035 |  | 
|  | 3036 | /// An iterator for PhiNodeSet. | 
|  | 3037 | class PhiNodeSetIterator { | 
|  | 3038 | PhiNodeSet * const Set; | 
|  | 3039 | size_t CurrentIndex = 0; | 
|  | 3040 |  | 
|  | 3041 | public: | 
|  | 3042 | /// The constructor. Start should point to either a valid element, or be equal | 
|  | 3043 | /// to the size of the underlying SmallVector of the PhiNodeSet. | 
|  | 3044 | PhiNodeSetIterator(PhiNodeSet * const Set, size_t Start); | 
|  | 3045 | PHINode * operator*() const; | 
|  | 3046 | PhiNodeSetIterator& operator++(); | 
|  | 3047 | bool operator==(const PhiNodeSetIterator &RHS) const; | 
|  | 3048 | bool operator!=(const PhiNodeSetIterator &RHS) const; | 
|  | 3049 | }; | 
|  | 3050 |  | 
|  | 3051 | /// Keeps a set of PHINodes. | 
|  | 3052 | /// | 
|  | 3053 | /// This is a minimal set implementation for a specific use case: | 
|  | 3054 | /// It is very fast when there are very few elements, but also provides good | 
|  | 3055 | /// performance when there are many. It is similar to SmallPtrSet, but also | 
|  | 3056 | /// provides iteration by insertion order, which is deterministic and stable | 
|  | 3057 | /// across runs. It is also similar to SmallSetVector, but provides removing | 
|  | 3058 | /// elements in O(1) time. This is achieved by not actually removing the element | 
|  | 3059 | /// from the underlying vector, so comes at the cost of using more memory, but | 
|  | 3060 | /// that is fine, since PhiNodeSets are used as short lived objects. | 
|  | 3061 | class PhiNodeSet { | 
|  | 3062 | friend class PhiNodeSetIterator; | 
|  | 3063 |  | 
|  | 3064 | using MapType = SmallDenseMap<PHINode *, size_t, 32>; | 
|  | 3065 | using iterator =  PhiNodeSetIterator; | 
|  | 3066 |  | 
|  | 3067 | /// Keeps the elements in the order of their insertion in the underlying | 
|  | 3068 | /// vector. To achieve constant time removal, it never deletes any element. | 
|  | 3069 | SmallVector<PHINode *, 32> NodeList; | 
|  | 3070 |  | 
|  | 3071 | /// Keeps the elements in the underlying set implementation. This (and not the | 
|  | 3072 | /// NodeList defined above) is the source of truth on whether an element | 
|  | 3073 | /// is actually in the collection. | 
|  | 3074 | MapType NodeMap; | 
|  | 3075 |  | 
|  | 3076 | /// Points to the first valid (not deleted) element when the set is not empty | 
|  | 3077 | /// and the value is not zero. Equals to the size of the underlying vector | 
|  | 3078 | /// when the set is empty. When the value is 0, as in the beginning, the | 
|  | 3079 | /// first element may or may not be valid. | 
|  | 3080 | size_t FirstValidElement = 0; | 
|  | 3081 |  | 
|  | 3082 | public: | 
|  | 3083 | /// Inserts a new element to the collection. | 
|  | 3084 | /// \returns true if the element is actually added, i.e. was not in the | 
|  | 3085 | /// collection before the operation. | 
|  | 3086 | bool insert(PHINode *Ptr) { | 
|  | 3087 | if (NodeMap.insert(std::make_pair(Ptr, NodeList.size())).second) { | 
|  | 3088 | NodeList.push_back(Ptr); | 
|  | 3089 | return true; | 
|  | 3090 | } | 
|  | 3091 | return false; | 
|  | 3092 | } | 
|  | 3093 |  | 
|  | 3094 | /// Removes the element from the collection. | 
|  | 3095 | /// \returns whether the element is actually removed, i.e. was in the | 
|  | 3096 | /// collection before the operation. | 
|  | 3097 | bool erase(PHINode *Ptr) { | 
|  | 3098 | auto it = NodeMap.find(Ptr); | 
|  | 3099 | if (it != NodeMap.end()) { | 
|  | 3100 | NodeMap.erase(Ptr); | 
|  | 3101 | SkipRemovedElements(FirstValidElement); | 
|  | 3102 | return true; | 
|  | 3103 | } | 
|  | 3104 | return false; | 
|  | 3105 | } | 
|  | 3106 |  | 
|  | 3107 | /// Removes all elements and clears the collection. | 
|  | 3108 | void clear() { | 
|  | 3109 | NodeMap.clear(); | 
|  | 3110 | NodeList.clear(); | 
|  | 3111 | FirstValidElement = 0; | 
|  | 3112 | } | 
|  | 3113 |  | 
|  | 3114 | /// \returns an iterator that will iterate the elements in the order of | 
|  | 3115 | /// insertion. | 
|  | 3116 | iterator begin() { | 
|  | 3117 | if (FirstValidElement == 0) | 
|  | 3118 | SkipRemovedElements(FirstValidElement); | 
|  | 3119 | return PhiNodeSetIterator(this, FirstValidElement); | 
|  | 3120 | } | 
|  | 3121 |  | 
|  | 3122 | /// \returns an iterator that points to the end of the collection. | 
|  | 3123 | iterator end() { return PhiNodeSetIterator(this, NodeList.size()); } | 
|  | 3124 |  | 
|  | 3125 | /// Returns the number of elements in the collection. | 
|  | 3126 | size_t size() const { | 
|  | 3127 | return NodeMap.size(); | 
|  | 3128 | } | 
|  | 3129 |  | 
|  | 3130 | /// \returns 1 if the given element is in the collection, and 0 if otherwise. | 
|  | 3131 | size_t count(PHINode *Ptr) const { | 
|  | 3132 | return NodeMap.count(Ptr); | 
|  | 3133 | } | 
|  | 3134 |  | 
|  | 3135 | private: | 
|  | 3136 | /// Updates the CurrentIndex so that it will point to a valid element. | 
|  | 3137 | /// | 
|  | 3138 | /// If the element of NodeList at CurrentIndex is valid, it does not | 
|  | 3139 | /// change it. If there are no more valid elements, it updates CurrentIndex | 
|  | 3140 | /// to point to the end of the NodeList. | 
|  | 3141 | void SkipRemovedElements(size_t &CurrentIndex) { | 
|  | 3142 | while (CurrentIndex < NodeList.size()) { | 
|  | 3143 | auto it = NodeMap.find(NodeList[CurrentIndex]); | 
|  | 3144 | // If the element has been deleted and added again later, NodeMap will | 
|  | 3145 | // point to a different index, so CurrentIndex will still be invalid. | 
|  | 3146 | if (it != NodeMap.end() && it->second == CurrentIndex) | 
|  | 3147 | break; | 
|  | 3148 | ++CurrentIndex; | 
|  | 3149 | } | 
|  | 3150 | } | 
|  | 3151 | }; | 
|  | 3152 |  | 
|  | 3153 | PhiNodeSetIterator::PhiNodeSetIterator(PhiNodeSet *const Set, size_t Start) | 
|  | 3154 | : Set(Set), CurrentIndex(Start) {} | 
|  | 3155 |  | 
|  | 3156 | PHINode * PhiNodeSetIterator::operator*() const { | 
|  | 3157 | assert(CurrentIndex < Set->NodeList.size() && | 
|  | 3158 | "PhiNodeSet access out of range"); | 
|  | 3159 | return Set->NodeList[CurrentIndex]; | 
|  | 3160 | } | 
|  | 3161 |  | 
|  | 3162 | PhiNodeSetIterator& PhiNodeSetIterator::operator++() { | 
|  | 3163 | assert(CurrentIndex < Set->NodeList.size() && | 
|  | 3164 | "PhiNodeSet access out of range"); | 
|  | 3165 | ++CurrentIndex; | 
|  | 3166 | Set->SkipRemovedElements(CurrentIndex); | 
|  | 3167 | return *this; | 
|  | 3168 | } | 
|  | 3169 |  | 
|  | 3170 | bool PhiNodeSetIterator::operator==(const PhiNodeSetIterator &RHS) const { | 
|  | 3171 | return CurrentIndex == RHS.CurrentIndex; | 
|  | 3172 | } | 
|  | 3173 |  | 
|  | 3174 | bool PhiNodeSetIterator::operator!=(const PhiNodeSetIterator &RHS) const { | 
| Serge Guelton | 12c7a96 | 2018-11-19 10:05:28 +0000 | [diff] [blame] | 3175 | return !((*this) == RHS); | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3176 | } | 
|  | 3177 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3178 | /// Keep track of simplification of Phi nodes. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3179 | /// Accept the set of all phi nodes and erase phi node from this set | 
|  | 3180 | /// if it is simplified. | 
|  | 3181 | class SimplificationTracker { | 
|  | 3182 | DenseMap<Value *, Value *> Storage; | 
|  | 3183 | const SimplifyQuery &SQ; | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3184 | // Tracks newly created Phi nodes. The elements are iterated by insertion | 
|  | 3185 | // order. | 
|  | 3186 | PhiNodeSet AllPhiNodes; | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3187 | // Tracks newly created Select nodes. | 
|  | 3188 | SmallPtrSet<SelectInst *, 32> AllSelectNodes; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3189 |  | 
|  | 3190 | public: | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3191 | SimplificationTracker(const SimplifyQuery &sq) | 
|  | 3192 | : SQ(sq) {} | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3193 |  | 
|  | 3194 | Value *Get(Value *V) { | 
|  | 3195 | do { | 
|  | 3196 | auto SV = Storage.find(V); | 
|  | 3197 | if (SV == Storage.end()) | 
|  | 3198 | return V; | 
|  | 3199 | V = SV->second; | 
|  | 3200 | } while (true); | 
|  | 3201 | } | 
|  | 3202 |  | 
|  | 3203 | Value *Simplify(Value *Val) { | 
|  | 3204 | SmallVector<Value *, 32> WorkList; | 
|  | 3205 | SmallPtrSet<Value *, 32> Visited; | 
|  | 3206 | WorkList.push_back(Val); | 
|  | 3207 | while (!WorkList.empty()) { | 
|  | 3208 | auto P = WorkList.pop_back_val(); | 
|  | 3209 | if (!Visited.insert(P).second) | 
|  | 3210 | continue; | 
|  | 3211 | if (auto *PI = dyn_cast<Instruction>(P)) | 
|  | 3212 | if (Value *V = SimplifyInstruction(cast<Instruction>(PI), SQ)) { | 
|  | 3213 | for (auto *U : PI->users()) | 
|  | 3214 | WorkList.push_back(cast<Value>(U)); | 
|  | 3215 | Put(PI, V); | 
|  | 3216 | PI->replaceAllUsesWith(V); | 
|  | 3217 | if (auto *PHI = dyn_cast<PHINode>(PI)) | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3218 | AllPhiNodes.erase(PHI); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3219 | if (auto *Select = dyn_cast<SelectInst>(PI)) | 
|  | 3220 | AllSelectNodes.erase(Select); | 
|  | 3221 | PI->eraseFromParent(); | 
|  | 3222 | } | 
|  | 3223 | } | 
|  | 3224 | return Get(Val); | 
|  | 3225 | } | 
|  | 3226 |  | 
|  | 3227 | void Put(Value *From, Value *To) { | 
|  | 3228 | Storage.insert({ From, To }); | 
|  | 3229 | } | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3230 |  | 
|  | 3231 | void ReplacePhi(PHINode *From, PHINode *To) { | 
|  | 3232 | Value* OldReplacement = Get(From); | 
|  | 3233 | while (OldReplacement != From) { | 
|  | 3234 | From = To; | 
|  | 3235 | To = dyn_cast<PHINode>(OldReplacement); | 
|  | 3236 | OldReplacement = Get(From); | 
|  | 3237 | } | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3238 | assert(To && Get(To) == To && "Replacement PHI node is already replaced."); | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3239 | Put(From, To); | 
|  | 3240 | From->replaceAllUsesWith(To); | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3241 | AllPhiNodes.erase(From); | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3242 | From->eraseFromParent(); | 
|  | 3243 | } | 
|  | 3244 |  | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3245 | PhiNodeSet& newPhiNodes() { return AllPhiNodes; } | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3246 |  | 
|  | 3247 | void insertNewPhi(PHINode *PN) { AllPhiNodes.insert(PN); } | 
|  | 3248 |  | 
|  | 3249 | void insertNewSelect(SelectInst *SI) { AllSelectNodes.insert(SI); } | 
|  | 3250 |  | 
|  | 3251 | unsigned countNewPhiNodes() const { return AllPhiNodes.size(); } | 
|  | 3252 |  | 
|  | 3253 | unsigned countNewSelectNodes() const { return AllSelectNodes.size(); } | 
|  | 3254 |  | 
|  | 3255 | void destroyNewNodes(Type *CommonType) { | 
|  | 3256 | // For safe erasing, replace the uses with dummy value first. | 
|  | 3257 | auto Dummy = UndefValue::get(CommonType); | 
|  | 3258 | for (auto I : AllPhiNodes) { | 
|  | 3259 | I->replaceAllUsesWith(Dummy); | 
|  | 3260 | I->eraseFromParent(); | 
|  | 3261 | } | 
|  | 3262 | AllPhiNodes.clear(); | 
|  | 3263 | for (auto I : AllSelectNodes) { | 
|  | 3264 | I->replaceAllUsesWith(Dummy); | 
|  | 3265 | I->eraseFromParent(); | 
|  | 3266 | } | 
|  | 3267 | AllSelectNodes.clear(); | 
|  | 3268 | } | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3269 | }; | 
|  | 3270 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3271 | /// A helper class for combining addressing modes. | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3272 | class AddressingModeCombiner { | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3273 | typedef DenseMap<Value *, Value *> FoldAddrToValueMapping; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3274 | typedef std::pair<PHINode *, PHINode *> PHIPair; | 
|  | 3275 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3276 | private: | 
|  | 3277 | /// The addressing modes we've collected. | 
|  | 3278 | SmallVector<ExtAddrMode, 16> AddrModes; | 
|  | 3279 |  | 
|  | 3280 | /// The field in which the AddrModes differ, when we have more than one. | 
|  | 3281 | ExtAddrMode::FieldName DifferentField = ExtAddrMode::NoField; | 
|  | 3282 |  | 
|  | 3283 | /// Are the AddrModes that we have all just equal to their original values? | 
|  | 3284 | bool AllAddrModesTrivial = true; | 
|  | 3285 |  | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3286 | /// Common Type for all different fields in addressing modes. | 
|  | 3287 | Type *CommonType; | 
|  | 3288 |  | 
|  | 3289 | /// SimplifyQuery for simplifyInstruction utility. | 
|  | 3290 | const SimplifyQuery &SQ; | 
|  | 3291 |  | 
|  | 3292 | /// Original Address. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3293 | Value *Original; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3294 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3295 | public: | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3296 | AddressingModeCombiner(const SimplifyQuery &_SQ, Value *OriginalValue) | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3297 | : CommonType(nullptr), SQ(_SQ), Original(OriginalValue) {} | 
|  | 3298 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3299 | /// Get the combined AddrMode | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3300 | const ExtAddrMode &getAddrMode() const { | 
|  | 3301 | return AddrModes[0]; | 
|  | 3302 | } | 
|  | 3303 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3304 | /// Add a new AddrMode if it's compatible with the AddrModes we already | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3305 | /// have. | 
|  | 3306 | /// \return True iff we succeeded in doing so. | 
|  | 3307 | bool addNewAddrMode(ExtAddrMode &NewAddrMode) { | 
|  | 3308 | // Take note of if we have any non-trivial AddrModes, as we need to detect | 
|  | 3309 | // when all AddrModes are trivial as then we would introduce a phi or select | 
|  | 3310 | // which just duplicates what's already there. | 
|  | 3311 | AllAddrModesTrivial = AllAddrModesTrivial && NewAddrMode.isTrivial(); | 
|  | 3312 |  | 
|  | 3313 | // If this is the first addrmode then everything is fine. | 
|  | 3314 | if (AddrModes.empty()) { | 
|  | 3315 | AddrModes.emplace_back(NewAddrMode); | 
|  | 3316 | return true; | 
|  | 3317 | } | 
|  | 3318 |  | 
|  | 3319 | // Figure out how different this is from the other address modes, which we | 
|  | 3320 | // can do just by comparing against the first one given that we only care | 
|  | 3321 | // about the cumulative difference. | 
|  | 3322 | ExtAddrMode::FieldName ThisDifferentField = | 
|  | 3323 | AddrModes[0].compare(NewAddrMode); | 
|  | 3324 | if (DifferentField == ExtAddrMode::NoField) | 
|  | 3325 | DifferentField = ThisDifferentField; | 
|  | 3326 | else if (DifferentField != ThisDifferentField) | 
|  | 3327 | DifferentField = ExtAddrMode::MultipleFields; | 
|  | 3328 |  | 
| Serguei Katkov | 17e5794 | 2018-01-23 12:07:49 +0000 | [diff] [blame] | 3329 | // If NewAddrMode differs in more than one dimension we cannot handle it. | 
|  | 3330 | bool CanHandle = DifferentField != ExtAddrMode::MultipleFields; | 
|  | 3331 |  | 
|  | 3332 | // If Scale Field is different then we reject. | 
|  | 3333 | CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField; | 
|  | 3334 |  | 
| Serguei Katkov | 4d1dd6b | 2018-01-09 04:37:06 +0000 | [diff] [blame] | 3335 | // We also must reject the case when base offset is different and | 
|  | 3336 | // scale reg is not null, we cannot handle this case due to merge of | 
|  | 3337 | // different offsets will be used as ScaleReg. | 
| Serguei Katkov | 17e5794 | 2018-01-23 12:07:49 +0000 | [diff] [blame] | 3338 | CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField || | 
|  | 3339 | !NewAddrMode.ScaledReg); | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3340 |  | 
| Serguei Katkov | 17e5794 | 2018-01-23 12:07:49 +0000 | [diff] [blame] | 3341 | // We also must reject the case when GV is different and BaseReg installed | 
|  | 3342 | // due to we want to use base reg as a merge of GV values. | 
|  | 3343 | CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField || | 
|  | 3344 | !NewAddrMode.HasBaseReg); | 
|  | 3345 |  | 
|  | 3346 | // Even if NewAddMode is the same we still need to collect it due to | 
|  | 3347 | // original value is different. And later we will need all original values | 
|  | 3348 | // as anchors during finding the common Phi node. | 
|  | 3349 | if (CanHandle) | 
|  | 3350 | AddrModes.emplace_back(NewAddrMode); | 
|  | 3351 | else | 
|  | 3352 | AddrModes.clear(); | 
|  | 3353 |  | 
|  | 3354 | return CanHandle; | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3355 | } | 
|  | 3356 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3357 | /// Combine the addressing modes we've collected into a single | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3358 | /// addressing mode. | 
|  | 3359 | /// \return True iff we successfully combined them or we only had one so | 
|  | 3360 | /// didn't need to combine them anyway. | 
|  | 3361 | bool combineAddrModes() { | 
|  | 3362 | // If we have no AddrModes then they can't be combined. | 
|  | 3363 | if (AddrModes.size() == 0) | 
|  | 3364 | return false; | 
|  | 3365 |  | 
|  | 3366 | // A single AddrMode can trivially be combined. | 
| Serguei Katkov | 505359f | 2017-11-20 05:42:36 +0000 | [diff] [blame] | 3367 | if (AddrModes.size() == 1 || DifferentField == ExtAddrMode::NoField) | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3368 | return true; | 
|  | 3369 |  | 
|  | 3370 | // If the AddrModes we collected are all just equal to the value they are | 
|  | 3371 | // derived from then combining them wouldn't do anything useful. | 
|  | 3372 | if (AllAddrModesTrivial) | 
|  | 3373 | return false; | 
|  | 3374 |  | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 3375 | if (!addrModeCombiningAllowed()) | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3376 | return false; | 
|  | 3377 |  | 
|  | 3378 | // Build a map between <original value, basic block where we saw it> to | 
|  | 3379 | // value of base register. | 
| Serguei Katkov | 5036459 | 2017-11-29 05:51:26 +0000 | [diff] [blame] | 3380 | // Bail out if there is no common type. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3381 | FoldAddrToValueMapping Map; | 
| Serguei Katkov | 5036459 | 2017-11-29 05:51:26 +0000 | [diff] [blame] | 3382 | if (!initializeMap(Map)) | 
|  | 3383 | return false; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3384 |  | 
|  | 3385 | Value *CommonValue = findCommon(Map); | 
|  | 3386 | if (CommonValue) | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 3387 | AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3388 | return CommonValue != nullptr; | 
|  | 3389 | } | 
|  | 3390 |  | 
|  | 3391 | private: | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3392 | /// Initialize Map with anchor values. For address seen | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3393 | /// we set the value of different field saw in this address. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3394 | /// At the same time we find a common type for different field we will | 
|  | 3395 | /// use to create new Phi/Select nodes. Keep it in CommonType field. | 
| Serguei Katkov | 5036459 | 2017-11-29 05:51:26 +0000 | [diff] [blame] | 3396 | /// Return false if there is no common type found. | 
|  | 3397 | bool initializeMap(FoldAddrToValueMapping &Map) { | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3398 | // Keep track of keys where the value is null. We will need to replace it | 
|  | 3399 | // with constant null when we know the common type. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3400 | SmallVector<Value *, 2> NullValue; | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 3401 | Type *IntPtrTy = SQ.DL.getIntPtrType(AddrModes[0].OriginalValue->getType()); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3402 | for (auto &AM : AddrModes) { | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 3403 | Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3404 | if (DV) { | 
| Serguei Katkov | 5036459 | 2017-11-29 05:51:26 +0000 | [diff] [blame] | 3405 | auto *Type = DV->getType(); | 
|  | 3406 | if (CommonType && CommonType != Type) | 
|  | 3407 | return false; | 
|  | 3408 | CommonType = Type; | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3409 | Map[AM.OriginalValue] = DV; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3410 | } else { | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3411 | NullValue.push_back(AM.OriginalValue); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3412 | } | 
|  | 3413 | } | 
|  | 3414 | assert(CommonType && "At least one non-null value must be!"); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3415 | for (auto *V : NullValue) | 
|  | 3416 | Map[V] = Constant::getNullValue(CommonType); | 
| Serguei Katkov | 5036459 | 2017-11-29 05:51:26 +0000 | [diff] [blame] | 3417 | return true; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3418 | } | 
|  | 3419 |  | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3420 | /// We have mapping between value A and other value B where B was a field in | 
|  | 3421 | /// addressing mode represented by A. Also we have an original value C | 
|  | 3422 | /// representing an address we start with. Traversing from C through phi and | 
|  | 3423 | /// selects we ended up with A's in a map. This utility function tries to find | 
|  | 3424 | /// a value V which is a field in addressing mode C and traversing through phi | 
|  | 3425 | /// nodes and selects we will end up in corresponded values B in a map. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3426 | /// The utility will create a new Phi/Selects if needed. | 
|  | 3427 | // The simple example looks as follows: | 
|  | 3428 | // BB1: | 
|  | 3429 | //   p1 = b1 + 40 | 
|  | 3430 | //   br cond BB2, BB3 | 
|  | 3431 | // BB2: | 
|  | 3432 | //   p2 = b2 + 40 | 
|  | 3433 | //   br BB3 | 
|  | 3434 | // BB3: | 
|  | 3435 | //   p = phi [p1, BB1], [p2, BB2] | 
|  | 3436 | //   v = load p | 
|  | 3437 | // Map is | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3438 | //   p1 -> b1 | 
|  | 3439 | //   p2 -> b2 | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3440 | // Request is | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3441 | //   p -> ? | 
|  | 3442 | // The function tries to find or build phi [b1, BB1], [b2, BB2] in BB3. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3443 | Value *findCommon(FoldAddrToValueMapping &Map) { | 
| Eric Christopher | d72f78e | 2018-01-09 23:25:38 +0000 | [diff] [blame] | 3444 | // Tracks the simplification of newly created phi nodes. The reason we use | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3445 | // this mapping is because we will add new created Phi nodes in AddrToBase. | 
|  | 3446 | // Simplification of Phi nodes is recursive, so some Phi node may | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3447 | // be simplified after we added it to AddrToBase. In reality this | 
|  | 3448 | // simplification is possible only if original phi/selects were not | 
|  | 3449 | // simplified yet. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3450 | // Using this mapping we can find the current value in AddrToBase. | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3451 | SimplificationTracker ST(SQ); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3452 |  | 
|  | 3453 | // First step, DFS to create PHI nodes for all intermediate blocks. | 
|  | 3454 | // Also fill traverse order for the second step. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3455 | SmallVector<Value *, 32> TraverseOrder; | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3456 | InsertPlaceholders(Map, TraverseOrder, ST); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3457 |  | 
|  | 3458 | // Second Step, fill new nodes by merged values and simplify if possible. | 
|  | 3459 | FillPlaceholders(Map, TraverseOrder, ST); | 
|  | 3460 |  | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3461 | if (!AddrSinkNewSelects && ST.countNewSelectNodes() > 0) { | 
|  | 3462 | ST.destroyNewNodes(CommonType); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3463 | return nullptr; | 
|  | 3464 | } | 
|  | 3465 |  | 
|  | 3466 | // Now we'd like to match New Phi nodes to existed ones. | 
|  | 3467 | unsigned PhiNotMatchedCount = 0; | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3468 | if (!MatchPhiSet(ST, AddrSinkNewPhis, PhiNotMatchedCount)) { | 
|  | 3469 | ST.destroyNewNodes(CommonType); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3470 | return nullptr; | 
|  | 3471 | } | 
|  | 3472 |  | 
|  | 3473 | auto *Result = ST.Get(Map.find(Original)->second); | 
|  | 3474 | if (Result) { | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3475 | NumMemoryInstsPhiCreated += ST.countNewPhiNodes() + PhiNotMatchedCount; | 
|  | 3476 | NumMemoryInstsSelectCreated += ST.countNewSelectNodes(); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3477 | } | 
|  | 3478 | return Result; | 
|  | 3479 | } | 
|  | 3480 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3481 | /// Try to match PHI node to Candidate. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3482 | /// Matcher tracks the matched Phi nodes. | 
|  | 3483 | bool MatchPhiNode(PHINode *PHI, PHINode *Candidate, | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3484 | SmallSetVector<PHIPair, 8> &Matcher, | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3485 | PhiNodeSet &PhiNodesToMatch) { | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3486 | SmallVector<PHIPair, 8> WorkList; | 
|  | 3487 | Matcher.insert({ PHI, Candidate }); | 
| Mikael Holmen | 339daae | 2019-03-15 13:51:05 +0000 | [diff] [blame] | 3488 | SmallSet<PHINode *, 8> MatchedPHIs; | 
|  | 3489 | MatchedPHIs.insert(PHI); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3490 | WorkList.push_back({ PHI, Candidate }); | 
|  | 3491 | SmallSet<PHIPair, 8> Visited; | 
|  | 3492 | while (!WorkList.empty()) { | 
|  | 3493 | auto Item = WorkList.pop_back_val(); | 
|  | 3494 | if (!Visited.insert(Item).second) | 
|  | 3495 | continue; | 
|  | 3496 | // We iterate over all incoming values to Phi to compare them. | 
|  | 3497 | // If values are different and both of them Phi and the first one is a | 
|  | 3498 | // Phi we added (subject to match) and both of them is in the same basic | 
|  | 3499 | // block then we can match our pair if values match. So we state that | 
|  | 3500 | // these values match and add it to work list to verify that. | 
|  | 3501 | for (auto B : Item.first->blocks()) { | 
|  | 3502 | Value *FirstValue = Item.first->getIncomingValueForBlock(B); | 
|  | 3503 | Value *SecondValue = Item.second->getIncomingValueForBlock(B); | 
|  | 3504 | if (FirstValue == SecondValue) | 
|  | 3505 | continue; | 
|  | 3506 |  | 
|  | 3507 | PHINode *FirstPhi = dyn_cast<PHINode>(FirstValue); | 
|  | 3508 | PHINode *SecondPhi = dyn_cast<PHINode>(SecondValue); | 
|  | 3509 |  | 
|  | 3510 | // One of them is not Phi or | 
|  | 3511 | // The first one is not Phi node from the set we'd like to match or | 
|  | 3512 | // Phi nodes from different basic blocks then | 
|  | 3513 | // we will not be able to match. | 
|  | 3514 | if (!FirstPhi || !SecondPhi || !PhiNodesToMatch.count(FirstPhi) || | 
|  | 3515 | FirstPhi->getParent() != SecondPhi->getParent()) | 
|  | 3516 | return false; | 
|  | 3517 |  | 
|  | 3518 | // If we already matched them then continue. | 
|  | 3519 | if (Matcher.count({ FirstPhi, SecondPhi })) | 
|  | 3520 | continue; | 
|  | 3521 | // So the values are different and does not match. So we need them to | 
| Mikael Holmen | 339daae | 2019-03-15 13:51:05 +0000 | [diff] [blame] | 3522 | // match. (But we register no more than one match per PHI node, so that | 
|  | 3523 | // we won't later try to replace them twice.) | 
| Jesper Antonsson | 39b81f1 | 2019-09-27 13:01:37 +0000 | [diff] [blame] | 3524 | if (MatchedPHIs.insert(FirstPhi).second) | 
| Mikael Holmen | 339daae | 2019-03-15 13:51:05 +0000 | [diff] [blame] | 3525 | Matcher.insert({ FirstPhi, SecondPhi }); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3526 | // But me must check it. | 
|  | 3527 | WorkList.push_back({ FirstPhi, SecondPhi }); | 
|  | 3528 | } | 
|  | 3529 | } | 
|  | 3530 | return true; | 
|  | 3531 | } | 
|  | 3532 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3533 | /// For the given set of PHI nodes (in the SimplificationTracker) try | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3534 | /// to find their equivalents. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3535 | /// Returns false if this matching fails and creation of new Phi is disabled. | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3536 | bool MatchPhiSet(SimplificationTracker &ST, bool AllowNewPhiNodes, | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3537 | unsigned &PhiNotMatchedCount) { | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3538 | // Matched and PhiNodesToMatch iterate their elements in a deterministic | 
|  | 3539 | // order, so the replacements (ReplacePhi) are also done in a deterministic | 
|  | 3540 | // order. | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3541 | SmallSetVector<PHIPair, 8> Matched; | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3542 | SmallPtrSet<PHINode *, 8> WillNotMatch; | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3543 | PhiNodeSet &PhiNodesToMatch = ST.newPhiNodes(); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3544 | while (PhiNodesToMatch.size()) { | 
|  | 3545 | PHINode *PHI = *PhiNodesToMatch.begin(); | 
|  | 3546 |  | 
|  | 3547 | // Add us, if no Phi nodes in the basic block we do not match. | 
|  | 3548 | WillNotMatch.clear(); | 
|  | 3549 | WillNotMatch.insert(PHI); | 
|  | 3550 |  | 
|  | 3551 | // Traverse all Phis until we found equivalent or fail to do that. | 
|  | 3552 | bool IsMatched = false; | 
|  | 3553 | for (auto &P : PHI->getParent()->phis()) { | 
|  | 3554 | if (&P == PHI) | 
|  | 3555 | continue; | 
|  | 3556 | if ((IsMatched = MatchPhiNode(PHI, &P, Matched, PhiNodesToMatch))) | 
|  | 3557 | break; | 
|  | 3558 | // If it does not match, collect all Phi nodes from matcher. | 
|  | 3559 | // if we end up with no match, them all these Phi nodes will not match | 
|  | 3560 | // later. | 
|  | 3561 | for (auto M : Matched) | 
|  | 3562 | WillNotMatch.insert(M.first); | 
|  | 3563 | Matched.clear(); | 
|  | 3564 | } | 
|  | 3565 | if (IsMatched) { | 
| Serguei Katkov | a20e05b | 2018-03-12 03:50:07 +0000 | [diff] [blame] | 3566 | // Replace all matched values and erase them. | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3567 | for (auto MV : Matched) | 
|  | 3568 | ST.ReplacePhi(MV.first, MV.second); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3569 | Matched.clear(); | 
|  | 3570 | continue; | 
|  | 3571 | } | 
|  | 3572 | // If we are not allowed to create new nodes then bail out. | 
|  | 3573 | if (!AllowNewPhiNodes) | 
|  | 3574 | return false; | 
|  | 3575 | // Just remove all seen values in matcher. They will not match anything. | 
|  | 3576 | PhiNotMatchedCount += WillNotMatch.size(); | 
|  | 3577 | for (auto *P : WillNotMatch) | 
| Ali Tamur | d482b01 | 2018-11-12 21:43:43 +0000 | [diff] [blame] | 3578 | PhiNodesToMatch.erase(P); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3579 | } | 
|  | 3580 | return true; | 
|  | 3581 | } | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3582 | /// Fill the placeholders with values from predecessors and simplify them. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3583 | void FillPlaceholders(FoldAddrToValueMapping &Map, | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3584 | SmallVectorImpl<Value *> &TraverseOrder, | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3585 | SimplificationTracker &ST) { | 
|  | 3586 | while (!TraverseOrder.empty()) { | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3587 | Value *Current = TraverseOrder.pop_back_val(); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3588 | assert(Map.find(Current) != Map.end() && "No node to fill!!!"); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3589 | Value *V = Map[Current]; | 
|  | 3590 |  | 
|  | 3591 | if (SelectInst *Select = dyn_cast<SelectInst>(V)) { | 
|  | 3592 | // CurrentValue also must be Select. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3593 | auto *CurrentSelect = cast<SelectInst>(Current); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3594 | auto *TrueValue = CurrentSelect->getTrueValue(); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3595 | assert(Map.find(TrueValue) != Map.end() && "No True Value!"); | 
|  | 3596 | Select->setTrueValue(ST.Get(Map[TrueValue])); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3597 | auto *FalseValue = CurrentSelect->getFalseValue(); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3598 | assert(Map.find(FalseValue) != Map.end() && "No False Value!"); | 
|  | 3599 | Select->setFalseValue(ST.Get(Map[FalseValue])); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3600 | } else { | 
|  | 3601 | // Must be a Phi node then. | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3602 | auto *PHI = cast<PHINode>(V); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3603 | // Fill the Phi node with values from predecessors. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3604 | for (auto B : predecessors(PHI->getParent())) { | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3605 | Value *PV = cast<PHINode>(Current)->getIncomingValueForBlock(B); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3606 | assert(Map.find(PV) != Map.end() && "No predecessor Value!"); | 
|  | 3607 | PHI->addIncoming(ST.Get(Map[PV]), B); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3608 | } | 
|  | 3609 | } | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3610 | Map[Current] = ST.Simplify(V); | 
|  | 3611 | } | 
|  | 3612 | } | 
|  | 3613 |  | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3614 | /// Starting from original value recursively iterates over def-use chain up to | 
|  | 3615 | /// known ending values represented in a map. For each traversed phi/select | 
|  | 3616 | /// inserts a placeholder Phi or Select. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3617 | /// Reports all new created Phi/Select nodes by adding them to set. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3618 | /// Also reports and order in what values have been traversed. | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3619 | void InsertPlaceholders(FoldAddrToValueMapping &Map, | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3620 | SmallVectorImpl<Value *> &TraverseOrder, | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3621 | SimplificationTracker &ST) { | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3622 | SmallVector<Value *, 32> Worklist; | 
|  | 3623 | assert((isa<PHINode>(Original) || isa<SelectInst>(Original)) && | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3624 | "Address must be a Phi or Select node"); | 
|  | 3625 | auto *Dummy = UndefValue::get(CommonType); | 
|  | 3626 | Worklist.push_back(Original); | 
|  | 3627 | while (!Worklist.empty()) { | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3628 | Value *Current = Worklist.pop_back_val(); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3629 | // if it is already visited or it is an ending value then skip it. | 
|  | 3630 | if (Map.find(Current) != Map.end()) | 
|  | 3631 | continue; | 
|  | 3632 | TraverseOrder.push_back(Current); | 
|  | 3633 |  | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3634 | // CurrentValue must be a Phi node or select. All others must be covered | 
|  | 3635 | // by anchors. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3636 | if (SelectInst *CurrentSelect = dyn_cast<SelectInst>(Current)) { | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3637 | // Is it OK to get metadata from OrigSelect?! | 
|  | 3638 | // Create a Select placeholder with dummy value. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3639 | SelectInst *Select = SelectInst::Create( | 
|  | 3640 | CurrentSelect->getCondition(), Dummy, Dummy, | 
|  | 3641 | CurrentSelect->getName(), CurrentSelect, CurrentSelect); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3642 | Map[Current] = Select; | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3643 | ST.insertNewSelect(Select); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3644 | // We are interested in True and False values. | 
|  | 3645 | Worklist.push_back(CurrentSelect->getTrueValue()); | 
|  | 3646 | Worklist.push_back(CurrentSelect->getFalseValue()); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3647 | } else { | 
|  | 3648 | // It must be a Phi node then. | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3649 | PHINode *CurrentPhi = cast<PHINode>(Current); | 
|  | 3650 | unsigned PredCount = CurrentPhi->getNumIncomingValues(); | 
|  | 3651 | PHINode *PHI = | 
|  | 3652 | PHINode::Create(CommonType, PredCount, "sunk_phi", CurrentPhi); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3653 | Map[Current] = PHI; | 
| Bjorn Pettersson | bf3213e | 2018-03-20 09:06:37 +0000 | [diff] [blame] | 3654 | ST.insertNewPhi(PHI); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 3655 | for (Value *P : CurrentPhi->incoming_values()) | 
|  | 3656 | Worklist.push_back(P); | 
| Serguei Katkov | d5d8d54 | 2017-11-05 05:50:33 +0000 | [diff] [blame] | 3657 | } | 
|  | 3658 | } | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3659 | } | 
| John Brawn | 70cdb5b | 2017-11-24 14:10:45 +0000 | [diff] [blame] | 3660 |  | 
|  | 3661 | bool addrModeCombiningAllowed() { | 
|  | 3662 | if (DisableComplexAddrModes) | 
|  | 3663 | return false; | 
|  | 3664 | switch (DifferentField) { | 
|  | 3665 | default: | 
|  | 3666 | return false; | 
|  | 3667 | case ExtAddrMode::BaseRegField: | 
|  | 3668 | return AddrSinkCombineBaseReg; | 
|  | 3669 | case ExtAddrMode::BaseGVField: | 
|  | 3670 | return AddrSinkCombineBaseGV; | 
|  | 3671 | case ExtAddrMode::BaseOffsField: | 
|  | 3672 | return AddrSinkCombineBaseOffs; | 
|  | 3673 | case ExtAddrMode::ScaledRegField: | 
|  | 3674 | return AddrSinkCombineScaledReg; | 
|  | 3675 | } | 
|  | 3676 | } | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 3677 | }; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 3678 | } // end anonymous namespace | 
|  | 3679 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 3680 | /// Try adding ScaleReg*Scale to the current addressing mode. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3681 | /// Return true and update AddrMode if this addr mode is legal for the target, | 
|  | 3682 | /// false if not. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 3683 | bool AddressingModeMatcher::matchScaledValue(Value *ScaleReg, int64_t Scale, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3684 | unsigned Depth) { | 
|  | 3685 | // If Scale is 1, then this is the same as adding ScaleReg to the addressing | 
|  | 3686 | // mode.  Just process that directly. | 
|  | 3687 | if (Scale == 1) | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 3688 | return matchAddr(ScaleReg, Depth); | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 3689 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3690 | // If the scale is 0, it takes nothing to add this. | 
|  | 3691 | if (Scale == 0) | 
|  | 3692 | return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 3693 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3694 | // If we already have a scale of this value, we can add to it, otherwise, we | 
|  | 3695 | // need an available scale field. | 
|  | 3696 | if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) | 
|  | 3697 | return false; | 
|  | 3698 |  | 
|  | 3699 | ExtAddrMode TestAddrMode = AddrMode; | 
|  | 3700 |  | 
|  | 3701 | // Add scale to turn X*4+X*3 -> X*7.  This could also do things like | 
|  | 3702 | // [A+B + A*7] -> [B+A*8]. | 
|  | 3703 | TestAddrMode.Scale += Scale; | 
|  | 3704 | TestAddrMode.ScaledReg = ScaleReg; | 
|  | 3705 |  | 
|  | 3706 | // If the new address isn't legal, bail out. | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 3707 | if (!TLI.isLegalAddressingMode(DL, TestAddrMode, AccessTy, AddrSpace)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3708 | return false; | 
|  | 3709 |  | 
|  | 3710 | // It was legal, so commit it. | 
|  | 3711 | AddrMode = TestAddrMode; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 3712 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3713 | // Okay, we decided that we can add ScaleReg+Scale to AddrMode.  Check now | 
|  | 3714 | // to see if ScaleReg is actually X+C.  If so, we can turn this into adding | 
|  | 3715 | // X*Scale + C*Scale to addr mode. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 3716 | ConstantInt *CI = nullptr; Value *AddLHS = nullptr; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3717 | if (isa<Instruction>(ScaleReg) &&  // not a constant expr. | 
|  | 3718 | match(ScaleReg, m_Add(m_Value(AddLHS), m_ConstantInt(CI)))) { | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 3719 | TestAddrMode.InBounds = false; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3720 | TestAddrMode.ScaledReg = AddLHS; | 
|  | 3721 | TestAddrMode.BaseOffs += CI->getSExtValue()*TestAddrMode.Scale; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 3722 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3723 | // If this addressing mode is legal, commit it and remember that we folded | 
|  | 3724 | // this instruction. | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 3725 | if (TLI.isLegalAddressingMode(DL, TestAddrMode, AccessTy, AddrSpace)) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3726 | AddrModeInsts.push_back(cast<Instruction>(ScaleReg)); | 
|  | 3727 | AddrMode = TestAddrMode; | 
|  | 3728 | return true; | 
|  | 3729 | } | 
|  | 3730 | } | 
|  | 3731 |  | 
|  | 3732 | // Otherwise, not (x+c)*scale, just return what we have. | 
|  | 3733 | return true; | 
|  | 3734 | } | 
|  | 3735 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 3736 | /// This is a little filter, which returns true if an addressing computation | 
|  | 3737 | /// involving I might be folded into a load/store accessing it. | 
|  | 3738 | /// This doesn't need to be perfect, but needs to accept at least | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3739 | /// the set of instructions that MatchOperationAddr can. | 
|  | 3740 | static bool MightBeFoldableInst(Instruction *I) { | 
|  | 3741 | switch (I->getOpcode()) { | 
|  | 3742 | case Instruction::BitCast: | 
| Eli Bendersky | f13a056 | 2014-05-22 00:02:52 +0000 | [diff] [blame] | 3743 | case Instruction::AddrSpaceCast: | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3744 | // Don't touch identity bitcasts. | 
|  | 3745 | if (I->getType() == I->getOperand(0)->getType()) | 
|  | 3746 | return false; | 
| Vedant Kumar | b3091da | 2018-07-06 20:17:42 +0000 | [diff] [blame] | 3747 | return I->getType()->isIntOrPtrTy(); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 3748 | case Instruction::PtrToInt: | 
|  | 3749 | // PtrToInt is always a noop, as we know that the int type is pointer sized. | 
|  | 3750 | return true; | 
|  | 3751 | case Instruction::IntToPtr: | 
|  | 3752 | // We know the input is intptr_t, so this is foldable. | 
|  | 3753 | return true; | 
|  | 3754 | case Instruction::Add: | 
|  | 3755 | return true; | 
|  | 3756 | case Instruction::Mul: | 
|  | 3757 | case Instruction::Shl: | 
|  | 3758 | // Can only handle X*C and X << C. | 
|  | 3759 | return isa<ConstantInt>(I->getOperand(1)); | 
|  | 3760 | case Instruction::GetElementPtr: | 
|  | 3761 | return true; | 
|  | 3762 | default: | 
|  | 3763 | return false; | 
|  | 3764 | } | 
|  | 3765 | } | 
|  | 3766 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3767 | /// Check whether or not \p Val is a legal instruction for \p TLI. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3768 | /// \note \p Val is assumed to be the product of some type promotion. | 
|  | 3769 | /// Therefore if \p Val has an undefined state in \p TLI, this is assumed | 
|  | 3770 | /// to be legal, as the non-promoted value would have had the same state. | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 3771 | static bool isPromotedInstructionLegal(const TargetLowering &TLI, | 
|  | 3772 | const DataLayout &DL, Value *Val) { | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3773 | Instruction *PromotedInst = dyn_cast<Instruction>(Val); | 
|  | 3774 | if (!PromotedInst) | 
|  | 3775 | return false; | 
|  | 3776 | int ISDOpcode = TLI.InstructionOpcodeToISD(PromotedInst->getOpcode()); | 
|  | 3777 | // If the ISDOpcode is undefined, it was undefined before the promotion. | 
|  | 3778 | if (!ISDOpcode) | 
|  | 3779 | return true; | 
|  | 3780 | // Otherwise, check if the promoted instruction is legal or not. | 
|  | 3781 | return TLI.isOperationLegalOrCustom( | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 3782 | ISDOpcode, TLI.getValueType(DL, PromotedInst->getType())); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3783 | } | 
|  | 3784 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 3785 | namespace { | 
|  | 3786 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3787 | /// Hepler class to perform type promotion. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3788 | class TypePromotionHelper { | 
| Guozhi Wei | 8c17f9a | 2018-08-15 22:08:26 +0000 | [diff] [blame] | 3789 | /// Utility function to add a promoted instruction \p ExtOpnd to | 
|  | 3790 | /// \p PromotedInsts and record the type of extension we have seen. | 
|  | 3791 | static void addPromotedInst(InstrToOrigTy &PromotedInsts, | 
|  | 3792 | Instruction *ExtOpnd, | 
|  | 3793 | bool IsSExt) { | 
|  | 3794 | ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension; | 
|  | 3795 | InstrToOrigTy::iterator It = PromotedInsts.find(ExtOpnd); | 
|  | 3796 | if (It != PromotedInsts.end()) { | 
|  | 3797 | // If the new extension is same as original, the information in | 
|  | 3798 | // PromotedInsts[ExtOpnd] is still correct. | 
|  | 3799 | if (It->second.getInt() == ExtTy) | 
|  | 3800 | return; | 
|  | 3801 |  | 
|  | 3802 | // Now the new extension is different from old extension, we make | 
|  | 3803 | // the type information invalid by setting extension type to | 
|  | 3804 | // BothExtension. | 
|  | 3805 | ExtTy = BothExtension; | 
|  | 3806 | } | 
|  | 3807 | PromotedInsts[ExtOpnd] = TypeIsSExt(ExtOpnd->getType(), ExtTy); | 
|  | 3808 | } | 
|  | 3809 |  | 
|  | 3810 | /// Utility function to query the original type of instruction \p Opnd | 
|  | 3811 | /// with a matched extension type. If the extension doesn't match, we | 
|  | 3812 | /// cannot use the information we had on the original type. | 
|  | 3813 | /// BothExtension doesn't match any extension type. | 
|  | 3814 | static const Type *getOrigType(const InstrToOrigTy &PromotedInsts, | 
|  | 3815 | Instruction *Opnd, | 
|  | 3816 | bool IsSExt) { | 
|  | 3817 | ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension; | 
|  | 3818 | InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd); | 
|  | 3819 | if (It != PromotedInsts.end() && It->second.getInt() == ExtTy) | 
|  | 3820 | return It->second.getPointer(); | 
|  | 3821 | return nullptr; | 
|  | 3822 | } | 
|  | 3823 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3824 | /// Utility function to check whether or not a sign or zero extension | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3825 | /// of \p Inst with \p ConsideredExtType can be moved through \p Inst by | 
|  | 3826 | /// either using the operands of \p Inst or promoting \p Inst. | 
|  | 3827 | /// The type of the extension is defined by \p IsSExt. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3828 | /// In other words, check if: | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3829 | /// ext (Ty Inst opnd1 opnd2 ... opndN) to ConsideredExtType. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3830 | /// #1 Promotion applies: | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3831 | /// ConsideredExtType Inst (ext opnd1 to ConsideredExtType, ...). | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3832 | /// #2 Operand reuses: | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3833 | /// ext opnd1 to ConsideredExtType. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3834 | /// \p PromotedInsts maps the instructions to their type before promotion. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3835 | static bool canGetThrough(const Instruction *Inst, Type *ConsideredExtType, | 
|  | 3836 | const InstrToOrigTy &PromotedInsts, bool IsSExt); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3837 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3838 | /// Utility function to determine if \p OpIdx should be promoted when | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3839 | /// promoting \p Inst. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3840 | static bool shouldExtOperand(const Instruction *Inst, int OpIdx) { | 
| Rafael Espindola | 84921b9 | 2015-10-24 23:11:13 +0000 | [diff] [blame] | 3841 | return !(isa<SelectInst>(Inst) && OpIdx == 0); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3842 | } | 
|  | 3843 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3844 | /// Utility function to promote the operand of \p Ext when this | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 3845 | /// operand is a promotable trunc or sext or zext. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3846 | /// \p PromotedInsts maps the instructions to their type before promotion. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3847 | /// \p CreatedInstsCost[out] contains the cost of all instructions | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3848 | /// created to promote the operand of Ext. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3849 | /// Newly added extensions are inserted in \p Exts. | 
|  | 3850 | /// Newly added truncates are inserted in \p Truncs. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3851 | /// Should never be called directly. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3852 | /// \return The promoted value which is used instead of Ext. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3853 | static Value *promoteOperandForTruncAndAnyExt( | 
|  | 3854 | Instruction *Ext, TypePromotionTransaction &TPT, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3855 | InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost, | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3856 | SmallVectorImpl<Instruction *> *Exts, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3857 | SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3858 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 3859 | /// Utility function to promote the operand of \p Ext when this | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3860 | /// operand is promotable and is not a supported trunc or sext. | 
|  | 3861 | /// \p PromotedInsts maps the instructions to their type before promotion. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3862 | /// \p CreatedInstsCost[out] contains the cost of all the instructions | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3863 | /// created to promote the operand of Ext. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3864 | /// Newly added extensions are inserted in \p Exts. | 
|  | 3865 | /// Newly added truncates are inserted in \p Truncs. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3866 | /// Should never be called directly. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3867 | /// \return The promoted value which is used instead of Ext. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3868 | static Value *promoteOperandForOther(Instruction *Ext, | 
|  | 3869 | TypePromotionTransaction &TPT, | 
|  | 3870 | InstrToOrigTy &PromotedInsts, | 
|  | 3871 | unsigned &CreatedInstsCost, | 
|  | 3872 | SmallVectorImpl<Instruction *> *Exts, | 
|  | 3873 | SmallVectorImpl<Instruction *> *Truncs, | 
|  | 3874 | const TargetLowering &TLI, bool IsSExt); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3875 |  | 
|  | 3876 | /// \see promoteOperandForOther. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3877 | static Value *signExtendOperandForOther( | 
|  | 3878 | Instruction *Ext, TypePromotionTransaction &TPT, | 
|  | 3879 | InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost, | 
|  | 3880 | SmallVectorImpl<Instruction *> *Exts, | 
|  | 3881 | SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI) { | 
|  | 3882 | return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost, | 
|  | 3883 | Exts, Truncs, TLI, true); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3884 | } | 
|  | 3885 |  | 
|  | 3886 | /// \see promoteOperandForOther. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 3887 | static Value *zeroExtendOperandForOther( | 
|  | 3888 | Instruction *Ext, TypePromotionTransaction &TPT, | 
|  | 3889 | InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost, | 
|  | 3890 | SmallVectorImpl<Instruction *> *Exts, | 
|  | 3891 | SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI) { | 
|  | 3892 | return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInstsCost, | 
|  | 3893 | Exts, Truncs, TLI, false); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3894 | } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3895 |  | 
|  | 3896 | public: | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3897 | /// Type for the utility function that promotes the operand of Ext. | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 3898 | using Action = Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT, | 
|  | 3899 | InstrToOrigTy &PromotedInsts, | 
|  | 3900 | unsigned &CreatedInstsCost, | 
|  | 3901 | SmallVectorImpl<Instruction *> *Exts, | 
|  | 3902 | SmallVectorImpl<Instruction *> *Truncs, | 
|  | 3903 | const TargetLowering &TLI); | 
|  | 3904 |  | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 3905 | /// Given a sign/zero extend instruction \p Ext, return the appropriate | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3906 | /// action to promote the operand of \p Ext instead of using Ext. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3907 | /// \return NULL if no promotable action is possible with the current | 
|  | 3908 | /// sign extension. | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 3909 | /// \p InsertedInsts keeps track of all the instructions inserted by the | 
|  | 3910 | /// other CodeGenPrepare optimizations. This information is important | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3911 | /// because we do not want to promote these instructions as CodeGenPrepare | 
|  | 3912 | /// will reinsert them later. Thus creating an infinite loop: create/remove. | 
|  | 3913 | /// \p PromotedInsts maps the instructions to their type before promotion. | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 3914 | static Action getAction(Instruction *Ext, const SetOfInstrs &InsertedInsts, | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3915 | const TargetLowering &TLI, | 
|  | 3916 | const InstrToOrigTy &PromotedInsts); | 
|  | 3917 | }; | 
|  | 3918 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 3919 | } // end anonymous namespace | 
|  | 3920 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3921 | bool TypePromotionHelper::canGetThrough(const Instruction *Inst, | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3922 | Type *ConsideredExtType, | 
|  | 3923 | const InstrToOrigTy &PromotedInsts, | 
|  | 3924 | bool IsSExt) { | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3925 | // The promotion helper does not know how to deal with vector types yet. | 
|  | 3926 | // To be able to fix that, we would need to fix the places where we | 
|  | 3927 | // statically extend, e.g., constants and such. | 
|  | 3928 | if (Inst->getType()->isVectorTy()) | 
|  | 3929 | return false; | 
|  | 3930 |  | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3931 | // We can always get through zext. | 
|  | 3932 | if (isa<ZExtInst>(Inst)) | 
|  | 3933 | return true; | 
|  | 3934 |  | 
|  | 3935 | // sext(sext) is ok too. | 
|  | 3936 | if (IsSExt && isa<SExtInst>(Inst)) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3937 | return true; | 
|  | 3938 |  | 
|  | 3939 | // We can get through binary operator, if it is legal. In other words, the | 
|  | 3940 | // binary operator must have a nuw or nsw flag. | 
|  | 3941 | const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst); | 
|  | 3942 | if (BinOp && isa<OverflowingBinaryOperator>(BinOp) && | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3943 | ((!IsSExt && BinOp->hasNoUnsignedWrap()) || | 
|  | 3944 | (IsSExt && BinOp->hasNoSignedWrap()))) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3945 | return true; | 
|  | 3946 |  | 
| Guozhi Wei | c4c6b54 | 2018-06-05 21:03:52 +0000 | [diff] [blame] | 3947 | // ext(and(opnd, cst)) --> and(ext(opnd), ext(cst)) | 
|  | 3948 | if ((Inst->getOpcode() == Instruction::And || | 
|  | 3949 | Inst->getOpcode() == Instruction::Or)) | 
|  | 3950 | return true; | 
|  | 3951 |  | 
|  | 3952 | // ext(xor(opnd, cst)) --> xor(ext(opnd), ext(cst)) | 
|  | 3953 | if (Inst->getOpcode() == Instruction::Xor) { | 
|  | 3954 | const ConstantInt *Cst = dyn_cast<ConstantInt>(Inst->getOperand(1)); | 
|  | 3955 | // Make sure it is not a NOT. | 
|  | 3956 | if (Cst && !Cst->getValue().isAllOnesValue()) | 
|  | 3957 | return true; | 
|  | 3958 | } | 
|  | 3959 |  | 
|  | 3960 | // zext(shrl(opnd, cst)) --> shrl(zext(opnd), zext(cst)) | 
|  | 3961 | // It may change a poisoned value into a regular value, like | 
|  | 3962 | //     zext i32 (shrl i8 %val, 12)  -->  shrl i32 (zext i8 %val), 12 | 
|  | 3963 | //          poisoned value                    regular value | 
|  | 3964 | // It should be OK since undef covers valid value. | 
|  | 3965 | if (Inst->getOpcode() == Instruction::LShr && !IsSExt) | 
|  | 3966 | return true; | 
|  | 3967 |  | 
|  | 3968 | // and(ext(shl(opnd, cst)), cst) --> and(shl(ext(opnd), ext(cst)), cst) | 
|  | 3969 | // It may change a poisoned value into a regular value, like | 
|  | 3970 | //     zext i32 (shl i8 %val, 12)  -->  shl i32 (zext i8 %val), 12 | 
|  | 3971 | //          poisoned value                    regular value | 
|  | 3972 | // It should be OK since undef covers valid value. | 
|  | 3973 | if (Inst->getOpcode() == Instruction::Shl && Inst->hasOneUse()) { | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3974 | const auto *ExtInst = cast<const Instruction>(*Inst->user_begin()); | 
| Guozhi Wei | c4c6b54 | 2018-06-05 21:03:52 +0000 | [diff] [blame] | 3975 | if (ExtInst->hasOneUse()) { | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3976 | const auto *AndInst = dyn_cast<const Instruction>(*ExtInst->user_begin()); | 
| Guozhi Wei | c4c6b54 | 2018-06-05 21:03:52 +0000 | [diff] [blame] | 3977 | if (AndInst && AndInst->getOpcode() == Instruction::And) { | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 3978 | const auto *Cst = dyn_cast<ConstantInt>(AndInst->getOperand(1)); | 
| Guozhi Wei | c4c6b54 | 2018-06-05 21:03:52 +0000 | [diff] [blame] | 3979 | if (Cst && | 
|  | 3980 | Cst->getValue().isIntN(Inst->getType()->getIntegerBitWidth())) | 
|  | 3981 | return true; | 
|  | 3982 | } | 
|  | 3983 | } | 
|  | 3984 | } | 
|  | 3985 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3986 | // Check if we can do the following simplification. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3987 | // ext(trunc(opnd)) --> ext(opnd) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3988 | if (!isa<TruncInst>(Inst)) | 
|  | 3989 | return false; | 
|  | 3990 |  | 
|  | 3991 | Value *OpndVal = Inst->getOperand(0); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 3992 | // Check if we can use this operand in the extension. | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 3993 | // If the type is larger than the result type of the extension, we cannot. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 3994 | if (!OpndVal->getType()->isIntegerTy() || | 
|  | 3995 | OpndVal->getType()->getIntegerBitWidth() > | 
|  | 3996 | ConsideredExtType->getIntegerBitWidth()) | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 3997 | return false; | 
|  | 3998 |  | 
|  | 3999 | // If the operand of the truncate is not an instruction, we will not have | 
|  | 4000 | // any information on the dropped bits. | 
|  | 4001 | // (Actually we could for constant but it is not worth the extra logic). | 
|  | 4002 | Instruction *Opnd = dyn_cast<Instruction>(OpndVal); | 
|  | 4003 | if (!Opnd) | 
|  | 4004 | return false; | 
|  | 4005 |  | 
|  | 4006 | // Check if the source of the type is narrow enough. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4007 | // I.e., check that trunc just drops extended bits of the same kind of | 
|  | 4008 | // the extension. | 
|  | 4009 | // #1 get the type of the operand and check the kind of the extended bits. | 
| Guozhi Wei | 8c17f9a | 2018-08-15 22:08:26 +0000 | [diff] [blame] | 4010 | const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt); | 
|  | 4011 | if (OpndType) | 
|  | 4012 | ; | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4013 | else if ((IsSExt && isa<SExtInst>(Opnd)) || (!IsSExt && isa<ZExtInst>(Opnd))) | 
|  | 4014 | OpndType = Opnd->getOperand(0)->getType(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4015 | else | 
|  | 4016 | return false; | 
|  | 4017 |  | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4018 | // #2 check that the truncate just drops extended bits. | 
| Rafael Espindola | 84921b9 | 2015-10-24 23:11:13 +0000 | [diff] [blame] | 4019 | return Inst->getType()->getIntegerBitWidth() >= | 
|  | 4020 | OpndType->getIntegerBitWidth(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4021 | } | 
|  | 4022 |  | 
|  | 4023 | TypePromotionHelper::Action TypePromotionHelper::getAction( | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 4024 | Instruction *Ext, const SetOfInstrs &InsertedInsts, | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4025 | const TargetLowering &TLI, const InstrToOrigTy &PromotedInsts) { | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4026 | assert((isa<SExtInst>(Ext) || isa<ZExtInst>(Ext)) && | 
|  | 4027 | "Unexpected instruction type"); | 
|  | 4028 | Instruction *ExtOpnd = dyn_cast<Instruction>(Ext->getOperand(0)); | 
|  | 4029 | Type *ExtTy = Ext->getType(); | 
|  | 4030 | bool IsSExt = isa<SExtInst>(Ext); | 
|  | 4031 | // If the operand of the extension is not an instruction, we cannot | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4032 | // get through. | 
|  | 4033 | // If it, check we can get through. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4034 | if (!ExtOpnd || !canGetThrough(ExtOpnd, ExtTy, PromotedInsts, IsSExt)) | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4035 | return nullptr; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4036 |  | 
|  | 4037 | // Do not promote if the operand has been added by codegenprepare. | 
|  | 4038 | // Otherwise, it means we are undoing an optimization that is likely to be | 
|  | 4039 | // redone, thus causing potential infinite loop. | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 4040 | if (isa<TruncInst>(ExtOpnd) && InsertedInsts.count(ExtOpnd)) | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4041 | return nullptr; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4042 |  | 
|  | 4043 | // SExt or Trunc instructions. | 
|  | 4044 | // Return the related handler. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4045 | if (isa<SExtInst>(ExtOpnd) || isa<TruncInst>(ExtOpnd) || | 
|  | 4046 | isa<ZExtInst>(ExtOpnd)) | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4047 | return promoteOperandForTruncAndAnyExt; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4048 |  | 
|  | 4049 | // Regular instruction. | 
|  | 4050 | // Abort early if we will have to insert non-free instructions. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4051 | if (!ExtOpnd->hasOneUse() && !TLI.isTruncateFree(ExtTy, ExtOpnd->getType())) | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4052 | return nullptr; | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4053 | return IsSExt ? signExtendOperandForOther : zeroExtendOperandForOther; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4054 | } | 
|  | 4055 |  | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4056 | Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt( | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 4057 | Instruction *SExt, TypePromotionTransaction &TPT, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4058 | InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost, | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4059 | SmallVectorImpl<Instruction *> *Exts, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4060 | SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4061 | // By construction, the operand of SExt is an instruction. Otherwise we cannot | 
|  | 4062 | // get through it and this method should not be called. | 
|  | 4063 | Instruction *SExtOpnd = cast<Instruction>(SExt->getOperand(0)); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4064 | Value *ExtVal = SExt; | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4065 | bool HasMergedNonFreeExt = false; | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4066 | if (isa<ZExtInst>(SExtOpnd)) { | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4067 | // Replace s|zext(zext(opnd)) | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4068 | // => zext(opnd). | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4069 | HasMergedNonFreeExt = !TLI.isExtFree(SExtOpnd); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4070 | Value *ZExt = | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4071 | TPT.createZExt(SExt, SExtOpnd->getOperand(0), SExt->getType()); | 
|  | 4072 | TPT.replaceAllUsesWith(SExt, ZExt); | 
|  | 4073 | TPT.eraseInstruction(SExt); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4074 | ExtVal = ZExt; | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4075 | } else { | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4076 | // Replace z|sext(trunc(opnd)) or sext(sext(opnd)) | 
|  | 4077 | // => z|sext(opnd). | 
| Quentin Colombet | b2c5c6d | 2014-09-11 21:22:14 +0000 | [diff] [blame] | 4078 | TPT.setOperand(SExt, 0, SExtOpnd->getOperand(0)); | 
|  | 4079 | } | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4080 | CreatedInstsCost = 0; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4081 |  | 
|  | 4082 | // Remove dead code. | 
|  | 4083 | if (SExtOpnd->use_empty()) | 
|  | 4084 | TPT.eraseInstruction(SExtOpnd); | 
|  | 4085 |  | 
| Quentin Colombet | 9dcb724 | 2014-09-15 18:26:58 +0000 | [diff] [blame] | 4086 | // Check if the extension is still needed. | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4087 | Instruction *ExtInst = dyn_cast<Instruction>(ExtVal); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4088 | if (!ExtInst || ExtInst->getType() != ExtInst->getOperand(0)->getType()) { | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4089 | if (ExtInst) { | 
|  | 4090 | if (Exts) | 
|  | 4091 | Exts->push_back(ExtInst); | 
|  | 4092 | CreatedInstsCost = !TLI.isExtFree(ExtInst) && !HasMergedNonFreeExt; | 
|  | 4093 | } | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4094 | return ExtVal; | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4095 | } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4096 |  | 
| Quentin Colombet | 9dcb724 | 2014-09-15 18:26:58 +0000 | [diff] [blame] | 4097 | // At this point we have: ext ty opnd to ty. | 
|  | 4098 | // Reassign the uses of ExtInst to the opnd and remove ExtInst. | 
|  | 4099 | Value *NextVal = ExtInst->getOperand(0); | 
|  | 4100 | TPT.eraseInstruction(ExtInst, NextVal); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4101 | return NextVal; | 
|  | 4102 | } | 
|  | 4103 |  | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4104 | Value *TypePromotionHelper::promoteOperandForOther( | 
|  | 4105 | Instruction *Ext, TypePromotionTransaction &TPT, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4106 | InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost, | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4107 | SmallVectorImpl<Instruction *> *Exts, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4108 | SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI, | 
|  | 4109 | bool IsSExt) { | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4110 | // By construction, the operand of Ext is an instruction. Otherwise we cannot | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4111 | // get through it and this method should not be called. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4112 | Instruction *ExtOpnd = cast<Instruction>(Ext->getOperand(0)); | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4113 | CreatedInstsCost = 0; | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4114 | if (!ExtOpnd->hasOneUse()) { | 
|  | 4115 | // ExtOpnd will be promoted. | 
|  | 4116 | // All its uses, but Ext, will need to use a truncated value of the | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4117 | // promoted version. | 
|  | 4118 | // Create the truncate now. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4119 | Value *Trunc = TPT.createTrunc(Ext, ExtOpnd->getType()); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4120 | if (Instruction *ITrunc = dyn_cast<Instruction>(Trunc)) { | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4121 | // Insert it just after the definition. | 
| Sanjay Patel | 674d2c2 | 2017-08-29 14:07:48 +0000 | [diff] [blame] | 4122 | ITrunc->moveAfter(ExtOpnd); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4123 | if (Truncs) | 
|  | 4124 | Truncs->push_back(ITrunc); | 
| Quentin Colombet | ac55b15 | 2014-09-16 22:36:07 +0000 | [diff] [blame] | 4125 | } | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4126 |  | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4127 | TPT.replaceAllUsesWith(ExtOpnd, Trunc); | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4128 | // Restore the operand of Ext (which has been replaced by the previous call | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4129 | // to replaceAllUsesWith) to avoid creating a cycle trunc <-> sext. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4130 | TPT.setOperand(Ext, 0, ExtOpnd); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4131 | } | 
|  | 4132 |  | 
|  | 4133 | // Get through the Instruction: | 
|  | 4134 | // 1. Update its type. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4135 | // 2. Replace the uses of Ext by Inst. | 
|  | 4136 | // 3. Extend each operand that needs to be extended. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4137 |  | 
|  | 4138 | // Remember the original type of the instruction before promotion. | 
|  | 4139 | // This is useful to know that the high bits are sign extended bits. | 
| Guozhi Wei | 8c17f9a | 2018-08-15 22:08:26 +0000 | [diff] [blame] | 4140 | addPromotedInst(PromotedInsts, ExtOpnd, IsSExt); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4141 | // Step #1. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4142 | TPT.mutateType(ExtOpnd, Ext->getType()); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4143 | // Step #2. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4144 | TPT.replaceAllUsesWith(Ext, ExtOpnd); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4145 | // Step #3. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4146 | Instruction *ExtForOpnd = Ext; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4147 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4148 | LLVM_DEBUG(dbgs() << "Propagate Ext to operands\n"); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4149 | for (int OpIdx = 0, EndOpIdx = ExtOpnd->getNumOperands(); OpIdx != EndOpIdx; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4150 | ++OpIdx) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4151 | LLVM_DEBUG(dbgs() << "Operand:\n" << *(ExtOpnd->getOperand(OpIdx)) << '\n'); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4152 | if (ExtOpnd->getOperand(OpIdx)->getType() == Ext->getType() || | 
|  | 4153 | !shouldExtOperand(ExtOpnd, OpIdx)) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4154 | LLVM_DEBUG(dbgs() << "No need to propagate\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4155 | continue; | 
|  | 4156 | } | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4157 | // Check if we can statically extend the operand. | 
|  | 4158 | Value *Opnd = ExtOpnd->getOperand(OpIdx); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4159 | if (const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4160 | LLVM_DEBUG(dbgs() << "Statically extend\n"); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4161 | unsigned BitWidth = Ext->getType()->getIntegerBitWidth(); | 
|  | 4162 | APInt CstVal = IsSExt ? Cst->getValue().sext(BitWidth) | 
|  | 4163 | : Cst->getValue().zext(BitWidth); | 
|  | 4164 | TPT.setOperand(ExtOpnd, OpIdx, ConstantInt::get(Ext->getType(), CstVal)); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4165 | continue; | 
|  | 4166 | } | 
|  | 4167 | // UndefValue are typed, so we have to statically sign extend them. | 
|  | 4168 | if (isa<UndefValue>(Opnd)) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4169 | LLVM_DEBUG(dbgs() << "Statically extend\n"); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4170 | TPT.setOperand(ExtOpnd, OpIdx, UndefValue::get(Ext->getType())); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4171 | continue; | 
|  | 4172 | } | 
|  | 4173 |  | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 4174 | // Otherwise we have to explicitly sign extend the operand. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4175 | // Check if Ext was reused to extend an operand. | 
|  | 4176 | if (!ExtForOpnd) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4177 | // If yes, create a new one. | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4178 | LLVM_DEBUG(dbgs() << "More operands to ext\n"); | 
| Quentin Colombet | 84f89cc | 2014-12-22 18:11:52 +0000 | [diff] [blame] | 4179 | Value *ValForExtOpnd = IsSExt ? TPT.createSExt(Ext, Opnd, Ext->getType()) | 
|  | 4180 | : TPT.createZExt(Ext, Opnd, Ext->getType()); | 
|  | 4181 | if (!isa<Instruction>(ValForExtOpnd)) { | 
|  | 4182 | TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd); | 
|  | 4183 | continue; | 
|  | 4184 | } | 
|  | 4185 | ExtForOpnd = cast<Instruction>(ValForExtOpnd); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4186 | } | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4187 | if (Exts) | 
|  | 4188 | Exts->push_back(ExtForOpnd); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4189 | TPT.setOperand(ExtForOpnd, 0, Opnd); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4190 |  | 
|  | 4191 | // Move the sign extension before the insertion point. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4192 | TPT.moveBefore(ExtForOpnd, ExtOpnd); | 
|  | 4193 | TPT.setOperand(ExtOpnd, OpIdx, ExtForOpnd); | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4194 | CreatedInstsCost += !TLI.isExtFree(ExtForOpnd); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4195 | // If more sext are required, new instructions will have to be created. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4196 | ExtForOpnd = nullptr; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4197 | } | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4198 | if (ExtForOpnd == Ext) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4199 | LLVM_DEBUG(dbgs() << "Extension is useless now\n"); | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4200 | TPT.eraseInstruction(Ext); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4201 | } | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4202 | return ExtOpnd; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4203 | } | 
|  | 4204 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4205 | /// Check whether or not promoting an instruction to a wider type is profitable. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4206 | /// \p NewCost gives the cost of extension instructions created by the | 
|  | 4207 | /// promotion. | 
|  | 4208 | /// \p OldCost gives the cost of extension instructions before the promotion | 
|  | 4209 | /// plus the number of instructions that have been | 
|  | 4210 | /// matched in the addressing mode the promotion. | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4211 | /// \p PromotedOperand is the value that has been promoted. | 
|  | 4212 | /// \return True if the promotion is profitable, false otherwise. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4213 | bool AddressingModeMatcher::isPromotionProfitable( | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4214 | unsigned NewCost, unsigned OldCost, Value *PromotedOperand) const { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4215 | LLVM_DEBUG(dbgs() << "OldCost: " << OldCost << "\tNewCost: " << NewCost | 
|  | 4216 | << '\n'); | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4217 | // The cost of the new extensions is greater than the cost of the | 
|  | 4218 | // old extension plus what we folded. | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4219 | // This is not profitable. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4220 | if (NewCost > OldCost) | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4221 | return false; | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4222 | if (NewCost < OldCost) | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4223 | return true; | 
|  | 4224 | // The promotion is neutral but it may help folding the sign extension in | 
|  | 4225 | // loads for instance. | 
|  | 4226 | // Check that we did not create an illegal instruction. | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 4227 | return isPromotedInstructionLegal(TLI, DL, PromotedOperand); | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4228 | } | 
|  | 4229 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4230 | /// Given an instruction or constant expr, see if we can fold the operation | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4231 | /// into the addressing mode. If so, update the addressing mode and return | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4232 | /// true, otherwise return false without modifying AddrMode. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4233 | /// If \p MovedAway is not NULL, it contains the information of whether or | 
|  | 4234 | /// not AddrInst has to be folded into the addressing mode on success. | 
|  | 4235 | /// If \p MovedAway == true, \p AddrInst will not be part of the addressing | 
|  | 4236 | /// because it has been moved away. | 
|  | 4237 | /// Thus AddrInst must not be added in the matched instructions. | 
|  | 4238 | /// This state can happen when AddrInst is a sext, since it may be moved away. | 
|  | 4239 | /// Therefore, AddrInst may not be valid when MovedAway is true and it must | 
|  | 4240 | /// not be referenced anymore. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4241 | bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode, | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4242 | unsigned Depth, | 
|  | 4243 | bool *MovedAway) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4244 | // Avoid exponential behavior on extremely deep expression trees. | 
|  | 4245 | if (Depth >= 5) return false; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4246 |  | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4247 | // By default, all matched instructions stay in place. | 
|  | 4248 | if (MovedAway) | 
|  | 4249 | *MovedAway = false; | 
|  | 4250 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4251 | switch (Opcode) { | 
|  | 4252 | case Instruction::PtrToInt: | 
|  | 4253 | // PtrToInt is always a noop, as we know that the int type is pointer sized. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4254 | return matchAddr(AddrInst->getOperand(0), Depth); | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 4255 | case Instruction::IntToPtr: { | 
|  | 4256 | auto AS = AddrInst->getType()->getPointerAddressSpace(); | 
|  | 4257 | auto PtrTy = MVT::getIntegerVT(DL.getPointerSizeInBits(AS)); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4258 | // This inttoptr is a no-op if the integer type is pointer sized. | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 4259 | if (TLI.getValueType(DL, AddrInst->getOperand(0)->getType()) == PtrTy) | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4260 | return matchAddr(AddrInst->getOperand(0), Depth); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4261 | return false; | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 4262 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4263 | case Instruction::BitCast: | 
|  | 4264 | // BitCast is always a noop, and we can handle it as long as it is | 
|  | 4265 | // int->int or pointer->pointer (we don't want int<->fp or something). | 
| Vedant Kumar | b3091da | 2018-07-06 20:17:42 +0000 | [diff] [blame] | 4266 | if (AddrInst->getOperand(0)->getType()->isIntOrPtrTy() && | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4267 | // Don't touch identity bitcasts.  These were probably put here by LSR, | 
|  | 4268 | // and we don't want to mess around with them.  Assume it knows what it | 
|  | 4269 | // is doing. | 
|  | 4270 | AddrInst->getOperand(0)->getType() != AddrInst->getType()) | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4271 | return matchAddr(AddrInst->getOperand(0), Depth); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4272 | return false; | 
| Matt Arsenault | f05b023 | 2015-05-26 16:59:43 +0000 | [diff] [blame] | 4273 | case Instruction::AddrSpaceCast: { | 
|  | 4274 | unsigned SrcAS | 
|  | 4275 | = AddrInst->getOperand(0)->getType()->getPointerAddressSpace(); | 
|  | 4276 | unsigned DestAS = AddrInst->getType()->getPointerAddressSpace(); | 
|  | 4277 | if (TLI.isNoopAddrSpaceCast(SrcAS, DestAS)) | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4278 | return matchAddr(AddrInst->getOperand(0), Depth); | 
| Matt Arsenault | f05b023 | 2015-05-26 16:59:43 +0000 | [diff] [blame] | 4279 | return false; | 
|  | 4280 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4281 | case Instruction::Add: { | 
|  | 4282 | // Check to see if we can merge in the RHS then the LHS.  If so, we win. | 
|  | 4283 | ExtAddrMode BackupAddrMode = AddrMode; | 
|  | 4284 | unsigned OldSize = AddrModeInsts.size(); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4285 | // Start a transaction at this point. | 
|  | 4286 | // The LHS may match but not the RHS. | 
|  | 4287 | // Therefore, we need a higher level restoration point to undo partially | 
|  | 4288 | // matched operation. | 
|  | 4289 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 4290 | TPT.getRestorationPoint(); | 
|  | 4291 |  | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 4292 | AddrMode.InBounds = false; | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4293 | if (matchAddr(AddrInst->getOperand(1), Depth+1) && | 
|  | 4294 | matchAddr(AddrInst->getOperand(0), Depth+1)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4295 | return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4296 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4297 | // Restore the old addr mode info. | 
|  | 4298 | AddrMode = BackupAddrMode; | 
|  | 4299 | AddrModeInsts.resize(OldSize); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4300 | TPT.rollback(LastKnownGood); | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4301 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4302 | // Otherwise this was over-aggressive.  Try merging in the LHS then the RHS. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4303 | if (matchAddr(AddrInst->getOperand(0), Depth+1) && | 
|  | 4304 | matchAddr(AddrInst->getOperand(1), Depth+1)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4305 | return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4306 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4307 | // Otherwise we definitely can't merge the ADD in. | 
|  | 4308 | AddrMode = BackupAddrMode; | 
|  | 4309 | AddrModeInsts.resize(OldSize); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4310 | TPT.rollback(LastKnownGood); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4311 | break; | 
|  | 4312 | } | 
|  | 4313 | //case Instruction::Or: | 
|  | 4314 | // TODO: We can handle "Or Val, Imm" iff this OR is equivalent to an ADD. | 
|  | 4315 | //break; | 
|  | 4316 | case Instruction::Mul: | 
|  | 4317 | case Instruction::Shl: { | 
|  | 4318 | // Can only handle X*C and X << C. | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 4319 | AddrMode.InBounds = false; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4320 | ConstantInt *RHS = dyn_cast<ConstantInt>(AddrInst->getOperand(1)); | 
| Philip Reames | 9c3cbee | 2017-10-30 23:59:51 +0000 | [diff] [blame] | 4321 | if (!RHS || RHS->getBitWidth() > 64) | 
| Sanjay Patel | d3bbfa1 | 2014-07-16 22:40:28 +0000 | [diff] [blame] | 4322 | return false; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4323 | int64_t Scale = RHS->getSExtValue(); | 
|  | 4324 | if (Opcode == Instruction::Shl) | 
|  | 4325 | Scale = 1LL << Scale; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4326 |  | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4327 | return matchScaledValue(AddrInst->getOperand(0), Scale, Depth); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4328 | } | 
|  | 4329 | case Instruction::GetElementPtr: { | 
|  | 4330 | // Scan the GEP.  We check it if it contains constant offsets and at most | 
|  | 4331 | // one variable offset. | 
|  | 4332 | int VariableOperand = -1; | 
|  | 4333 | unsigned VariableScale = 0; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4334 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4335 | int64_t ConstantOffset = 0; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4336 | gep_type_iterator GTI = gep_type_begin(AddrInst); | 
|  | 4337 | for (unsigned i = 1, e = AddrInst->getNumOperands(); i != e; ++i, ++GTI) { | 
| Peter Collingbourne | ab85225b | 2016-12-02 02:24:42 +0000 | [diff] [blame] | 4338 | if (StructType *STy = GTI.getStructTypeOrNull()) { | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 4339 | const StructLayout *SL = DL.getStructLayout(STy); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4340 | unsigned Idx = | 
|  | 4341 | cast<ConstantInt>(AddrInst->getOperand(i))->getZExtValue(); | 
|  | 4342 | ConstantOffset += SL->getElementOffset(Idx); | 
|  | 4343 | } else { | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 4344 | uint64_t TypeSize = DL.getTypeAllocSize(GTI.getIndexedType()); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4345 | if (ConstantInt *CI = dyn_cast<ConstantInt>(AddrInst->getOperand(i))) { | 
| Simon Pilgrim | ee82a79 | 2018-08-13 12:10:09 +0000 | [diff] [blame] | 4346 | const APInt &CVal = CI->getValue(); | 
|  | 4347 | if (CVal.getMinSignedBits() <= 64) { | 
|  | 4348 | ConstantOffset += CVal.getSExtValue() * TypeSize; | 
|  | 4349 | continue; | 
|  | 4350 | } | 
|  | 4351 | } | 
|  | 4352 | if (TypeSize) {  // Scales of zero don't do anything. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4353 | // We only allow one variable index at the moment. | 
|  | 4354 | if (VariableOperand != -1) | 
|  | 4355 | return false; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4356 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4357 | // Remember the variable index. | 
|  | 4358 | VariableOperand = i; | 
|  | 4359 | VariableScale = TypeSize; | 
|  | 4360 | } | 
|  | 4361 | } | 
|  | 4362 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4363 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4364 | // A common case is for the GEP to only do a constant offset.  In this case, | 
|  | 4365 | // just add it to the disp field and check validity. | 
|  | 4366 | if (VariableOperand == -1) { | 
|  | 4367 | AddrMode.BaseOffs += ConstantOffset; | 
| Matt Arsenault | f72b49b | 2015-06-04 16:17:38 +0000 | [diff] [blame] | 4368 | if (ConstantOffset == 0 || | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 4369 | TLI.isLegalAddressingMode(DL, AddrMode, AccessTy, AddrSpace)) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4370 | // Check to see if we can fold the base pointer in too. | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 4371 | if (matchAddr(AddrInst->getOperand(0), Depth+1)) { | 
|  | 4372 | if (!cast<GEPOperator>(AddrInst)->isInBounds()) | 
|  | 4373 | AddrMode.InBounds = false; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4374 | return true; | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 4375 | } | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4376 | } else if (EnableGEPOffsetSplit && isa<GetElementPtrInst>(AddrInst) && | 
|  | 4377 | TLI.shouldConsiderGEPOffsetSplit() && Depth == 0 && | 
|  | 4378 | ConstantOffset > 0) { | 
|  | 4379 | // Record GEPs with non-zero offsets as candidates for splitting in the | 
|  | 4380 | // event that the offset cannot fit into the r+i addressing mode. | 
|  | 4381 | // Simple and common case that only one GEP is used in calculating the | 
|  | 4382 | // address for the memory access. | 
|  | 4383 | Value *Base = AddrInst->getOperand(0); | 
|  | 4384 | auto *BaseI = dyn_cast<Instruction>(Base); | 
|  | 4385 | auto *GEP = cast<GetElementPtrInst>(AddrInst); | 
|  | 4386 | if (isa<Argument>(Base) || isa<GlobalValue>(Base) || | 
|  | 4387 | (BaseI && !isa<CastInst>(BaseI) && | 
|  | 4388 | !isa<GetElementPtrInst>(BaseI))) { | 
| Luis Marques | 2e46312 | 2019-06-17 10:54:12 +0000 | [diff] [blame] | 4389 | // Make sure the parent block allows inserting non-PHI instructions | 
|  | 4390 | // before the terminator. | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4391 | BasicBlock *Parent = | 
|  | 4392 | BaseI ? BaseI->getParent() : &GEP->getFunction()->getEntryBlock(); | 
| Luis Marques | 2e46312 | 2019-06-17 10:54:12 +0000 | [diff] [blame] | 4393 | if (!Parent->getTerminator()->isEHPad()) | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4394 | LargeOffsetGEP = std::make_pair(GEP, ConstantOffset); | 
|  | 4395 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4396 | } | 
|  | 4397 | AddrMode.BaseOffs -= ConstantOffset; | 
|  | 4398 | return false; | 
|  | 4399 | } | 
|  | 4400 |  | 
|  | 4401 | // Save the valid addressing mode in case we can't match. | 
|  | 4402 | ExtAddrMode BackupAddrMode = AddrMode; | 
|  | 4403 | unsigned OldSize = AddrModeInsts.size(); | 
|  | 4404 |  | 
|  | 4405 | // See if the scale and offset amount is valid for this target. | 
|  | 4406 | AddrMode.BaseOffs += ConstantOffset; | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 4407 | if (!cast<GEPOperator>(AddrInst)->isInBounds()) | 
|  | 4408 | AddrMode.InBounds = false; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4409 |  | 
|  | 4410 | // Match the base operand of the GEP. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4411 | if (!matchAddr(AddrInst->getOperand(0), Depth+1)) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4412 | // If it couldn't be matched, just stuff the value in a register. | 
|  | 4413 | if (AddrMode.HasBaseReg) { | 
|  | 4414 | AddrMode = BackupAddrMode; | 
|  | 4415 | AddrModeInsts.resize(OldSize); | 
|  | 4416 | return false; | 
|  | 4417 | } | 
|  | 4418 | AddrMode.HasBaseReg = true; | 
|  | 4419 | AddrMode.BaseReg = AddrInst->getOperand(0); | 
|  | 4420 | } | 
|  | 4421 |  | 
|  | 4422 | // Match the remaining variable portion of the GEP. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4423 | if (!matchScaledValue(AddrInst->getOperand(VariableOperand), VariableScale, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4424 | Depth)) { | 
|  | 4425 | // If it couldn't be matched, try stuffing the base into a register | 
|  | 4426 | // instead of matching it, and retrying the match of the scale. | 
|  | 4427 | AddrMode = BackupAddrMode; | 
|  | 4428 | AddrModeInsts.resize(OldSize); | 
|  | 4429 | if (AddrMode.HasBaseReg) | 
|  | 4430 | return false; | 
|  | 4431 | AddrMode.HasBaseReg = true; | 
|  | 4432 | AddrMode.BaseReg = AddrInst->getOperand(0); | 
|  | 4433 | AddrMode.BaseOffs += ConstantOffset; | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4434 | if (!matchScaledValue(AddrInst->getOperand(VariableOperand), | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4435 | VariableScale, Depth)) { | 
|  | 4436 | // If even that didn't work, bail. | 
|  | 4437 | AddrMode = BackupAddrMode; | 
|  | 4438 | AddrModeInsts.resize(OldSize); | 
|  | 4439 | return false; | 
|  | 4440 | } | 
|  | 4441 | } | 
|  | 4442 |  | 
|  | 4443 | return true; | 
|  | 4444 | } | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4445 | case Instruction::SExt: | 
|  | 4446 | case Instruction::ZExt: { | 
|  | 4447 | Instruction *Ext = dyn_cast<Instruction>(AddrInst); | 
|  | 4448 | if (!Ext) | 
| Sanjay Patel | d3bbfa1 | 2014-07-16 22:40:28 +0000 | [diff] [blame] | 4449 | return false; | 
| Sanjay Patel | ab60d04 | 2014-07-16 21:08:10 +0000 | [diff] [blame] | 4450 |  | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4451 | // Try to move this ext out of the way of the addressing mode. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4452 | // Ask for a method for doing so. | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4453 | TypePromotionHelper::Action TPH = | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 4454 | TypePromotionHelper::getAction(Ext, InsertedInsts, TLI, PromotedInsts); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4455 | if (!TPH) | 
|  | 4456 | return false; | 
|  | 4457 |  | 
|  | 4458 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 4459 | TPT.getRestorationPoint(); | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4460 | unsigned CreatedInstsCost = 0; | 
|  | 4461 | unsigned ExtCost = !TLI.isExtFree(Ext); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 4462 | Value *PromotedOperand = | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4463 | TPH(Ext, TPT, PromotedInsts, CreatedInstsCost, nullptr, nullptr, TLI); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4464 | // SExt has been moved away. | 
|  | 4465 | // Thus either it will be rematched later in the recursive calls or it is | 
|  | 4466 | // gone. Anyway, we must not fold it into the addressing mode at this point. | 
|  | 4467 | // E.g., | 
|  | 4468 | // op = add opnd, 1 | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4469 | // idx = ext op | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4470 | // addr = gep base, idx | 
|  | 4471 | // is now: | 
| Quentin Colombet | f5485bb | 2014-11-13 01:44:51 +0000 | [diff] [blame] | 4472 | // promotedOpnd = ext opnd            <- no match here | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4473 | // op = promoted_add promotedOpnd, 1  <- match (later in recursive calls) | 
|  | 4474 | // addr = gep base, op                <- match | 
|  | 4475 | if (MovedAway) | 
|  | 4476 | *MovedAway = true; | 
|  | 4477 |  | 
|  | 4478 | assert(PromotedOperand && | 
|  | 4479 | "TypePromotionHelper should have filtered out those cases"); | 
|  | 4480 |  | 
|  | 4481 | ExtAddrMode BackupAddrMode = AddrMode; | 
|  | 4482 | unsigned OldSize = AddrModeInsts.size(); | 
|  | 4483 |  | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4484 | if (!matchAddr(PromotedOperand, Depth) || | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4485 | // The total of the new cost is equal to the cost of the created | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4486 | // instructions. | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4487 | // The total of the old cost is equal to the cost of the extension plus | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4488 | // what we have saved in the addressing mode. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4489 | !isPromotionProfitable(CreatedInstsCost, | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 4490 | ExtCost + (AddrModeInsts.size() - OldSize), | 
| Quentin Colombet | 867c550 | 2014-02-14 22:23:22 +0000 | [diff] [blame] | 4491 | PromotedOperand)) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4492 | AddrMode = BackupAddrMode; | 
|  | 4493 | AddrModeInsts.resize(OldSize); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4494 | LLVM_DEBUG(dbgs() << "Sign extension does not pay off: rollback\n"); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4495 | TPT.rollback(LastKnownGood); | 
|  | 4496 | return false; | 
|  | 4497 | } | 
|  | 4498 | return true; | 
|  | 4499 | } | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4500 | } | 
|  | 4501 | return false; | 
|  | 4502 | } | 
|  | 4503 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4504 | /// If we can, try to add the value of 'Addr' into the current addressing mode. | 
|  | 4505 | /// If Addr can't be added to AddrMode this returns false and leaves AddrMode | 
|  | 4506 | /// unmodified. This assumes that Addr is either a pointer type or intptr_t | 
|  | 4507 | /// for the target. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4508 | /// | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4509 | bool AddressingModeMatcher::matchAddr(Value *Addr, unsigned Depth) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4510 | // Start a transaction at this point that we will rollback if the matching | 
|  | 4511 | // fails. | 
|  | 4512 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 4513 | TPT.getRestorationPoint(); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4514 | if (ConstantInt *CI = dyn_cast<ConstantInt>(Addr)) { | 
|  | 4515 | // Fold in immediates if legal for the target. | 
|  | 4516 | AddrMode.BaseOffs += CI->getSExtValue(); | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 4517 | if (TLI.isLegalAddressingMode(DL, AddrMode, AccessTy, AddrSpace)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4518 | return true; | 
|  | 4519 | AddrMode.BaseOffs -= CI->getSExtValue(); | 
|  | 4520 | } else if (GlobalValue *GV = dyn_cast<GlobalValue>(Addr)) { | 
|  | 4521 | // If this is a global variable, try to fold it into the addressing mode. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4522 | if (!AddrMode.BaseGV) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4523 | AddrMode.BaseGV = GV; | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 4524 | if (TLI.isLegalAddressingMode(DL, AddrMode, AccessTy, AddrSpace)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4525 | return true; | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4526 | AddrMode.BaseGV = nullptr; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4527 | } | 
|  | 4528 | } else if (Instruction *I = dyn_cast<Instruction>(Addr)) { | 
|  | 4529 | ExtAddrMode BackupAddrMode = AddrMode; | 
|  | 4530 | unsigned OldSize = AddrModeInsts.size(); | 
|  | 4531 |  | 
|  | 4532 | // Check to see if it is possible to fold this operation. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4533 | bool MovedAway = false; | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4534 | if (matchOperationAddr(I, I->getOpcode(), Depth, &MovedAway)) { | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4535 | // This instruction may have been moved away. If so, there is nothing | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4536 | // to check here. | 
|  | 4537 | if (MovedAway) | 
|  | 4538 | return true; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4539 | // Okay, it's possible to fold this.  Check to see if it is actually | 
|  | 4540 | // *profitable* to do so.  We use a simple cost model to avoid increasing | 
|  | 4541 | // register pressure too much. | 
|  | 4542 | if (I->hasOneUse() || | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4543 | isProfitableToFoldIntoAddressingMode(I, BackupAddrMode, AddrMode)) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4544 | AddrModeInsts.push_back(I); | 
|  | 4545 | return true; | 
|  | 4546 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4547 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4548 | // It isn't profitable to do this, roll back. | 
|  | 4549 | //cerr << "NOT FOLDING: " << *I; | 
|  | 4550 | AddrMode = BackupAddrMode; | 
|  | 4551 | AddrModeInsts.resize(OldSize); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4552 | TPT.rollback(LastKnownGood); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4553 | } | 
|  | 4554 | } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr)) { | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4555 | if (matchOperationAddr(CE, CE->getOpcode(), Depth)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4556 | return true; | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4557 | TPT.rollback(LastKnownGood); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4558 | } else if (isa<ConstantPointerNull>(Addr)) { | 
|  | 4559 | // Null pointer gets folded without affecting the addressing mode. | 
|  | 4560 | return true; | 
|  | 4561 | } | 
|  | 4562 |  | 
|  | 4563 | // Worse case, the target should support [reg] addressing modes. :) | 
|  | 4564 | if (!AddrMode.HasBaseReg) { | 
|  | 4565 | AddrMode.HasBaseReg = true; | 
|  | 4566 | AddrMode.BaseReg = Addr; | 
|  | 4567 | // Still check for legality in case the target supports [imm] but not [i+r]. | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 4568 | if (TLI.isLegalAddressingMode(DL, AddrMode, AccessTy, AddrSpace)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4569 | return true; | 
|  | 4570 | AddrMode.HasBaseReg = false; | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4571 | AddrMode.BaseReg = nullptr; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4572 | } | 
|  | 4573 |  | 
|  | 4574 | // If the base register is already taken, see if we can do [r+r]. | 
|  | 4575 | if (AddrMode.Scale == 0) { | 
|  | 4576 | AddrMode.Scale = 1; | 
|  | 4577 | AddrMode.ScaledReg = Addr; | 
| Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 4578 | if (TLI.isLegalAddressingMode(DL, AddrMode, AccessTy, AddrSpace)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4579 | return true; | 
|  | 4580 | AddrMode.Scale = 0; | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4581 | AddrMode.ScaledReg = nullptr; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4582 | } | 
|  | 4583 | // Couldn't match. | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4584 | TPT.rollback(LastKnownGood); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4585 | return false; | 
|  | 4586 | } | 
|  | 4587 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4588 | /// Check to see if all uses of OpVal by the specified inline asm call are due | 
|  | 4589 | /// to memory operands. If so, return true, otherwise return false. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4590 | static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 4591 | const TargetLowering &TLI, | 
|  | 4592 | const TargetRegisterInfo &TRI) { | 
| Sanjay Patel | 4137d51 | 2017-06-07 14:29:52 +0000 | [diff] [blame] | 4593 | const Function *F = CI->getFunction(); | 
| Eric Christopher | d75c00c | 2015-02-26 22:38:34 +0000 | [diff] [blame] | 4594 | TargetLowering::AsmOperandInfoVector TargetConstraints = | 
| Craig Topper | 95192f5 | 2020-04-11 21:45:09 -0700 | [diff] [blame] | 4595 | TLI.ParseConstraints(F->getParent()->getDataLayout(), &TRI, *CI); | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 4596 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4597 | for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) { | 
|  | 4598 | TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i]; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4599 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4600 | // Compute the constraint code and ConstraintType to use. | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 4601 | TLI.ComputeConstraintToUse(OpInfo, SDValue()); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4602 |  | 
|  | 4603 | // If this asm operand is our Value*, and if it isn't an indirect memory | 
|  | 4604 | // operand, we can't fold it! | 
|  | 4605 | if (OpInfo.CallOperandVal == OpVal && | 
|  | 4606 | (OpInfo.ConstraintType != TargetLowering::C_Memory || | 
|  | 4607 | !OpInfo.isIndirect)) | 
|  | 4608 | return false; | 
|  | 4609 | } | 
|  | 4610 |  | 
|  | 4611 | return true; | 
|  | 4612 | } | 
|  | 4613 |  | 
| Benjamin Kramer | fc638c1 | 2017-07-24 16:18:09 +0000 | [diff] [blame] | 4614 | // Max number of memory uses to look at before aborting the search to conserve | 
|  | 4615 | // compile time. | 
|  | 4616 | static constexpr int MaxMemoryUsesToScan = 20; | 
|  | 4617 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4618 | /// Recursively walk all the uses of I until we find a memory use. | 
|  | 4619 | /// If we find an obviously non-foldable instruction, return true. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4620 | /// Add the ultimately found memory instructions to MemoryUses. | 
| Eric Christopher | 11e4df7 | 2015-02-26 22:38:43 +0000 | [diff] [blame] | 4621 | static bool FindAllMemoryUses( | 
|  | 4622 | Instruction *I, | 
|  | 4623 | SmallVectorImpl<std::pair<Instruction *, unsigned>> &MemoryUses, | 
| Benjamin Kramer | fc638c1 | 2017-07-24 16:18:09 +0000 | [diff] [blame] | 4624 | SmallPtrSetImpl<Instruction *> &ConsideredInsts, const TargetLowering &TLI, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4625 | const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, | 
|  | 4626 | BlockFrequencyInfo *BFI, int SeenInsts = 0) { | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4627 | // If we already considered this instruction, we're done. | 
| David Blaikie | 70573dc | 2014-11-19 07:49:26 +0000 | [diff] [blame] | 4628 | if (!ConsideredInsts.insert(I).second) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4629 | return false; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4630 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4631 | // If this is an obviously unfoldable instruction, bail out. | 
|  | 4632 | if (!MightBeFoldableInst(I)) | 
|  | 4633 | return true; | 
|  | 4634 |  | 
|  | 4635 | // Loop over all the uses, recursively processing them. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 4636 | for (Use &U : I->uses()) { | 
| Benjamin Kramer | fc638c1 | 2017-07-24 16:18:09 +0000 | [diff] [blame] | 4637 | // Conservatively return true if we're seeing a large number or a deep chain | 
|  | 4638 | // of users. This avoids excessive compilation times in pathological cases. | 
|  | 4639 | if (SeenInsts++ >= MaxMemoryUsesToScan) | 
|  | 4640 | return true; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4641 |  | 
| Benjamin Kramer | fc638c1 | 2017-07-24 16:18:09 +0000 | [diff] [blame] | 4642 | Instruction *UserI = cast<Instruction>(U.getUser()); | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 4643 | if (LoadInst *LI = dyn_cast<LoadInst>(UserI)) { | 
|  | 4644 | MemoryUses.push_back(std::make_pair(LI, U.getOperandNo())); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4645 | continue; | 
|  | 4646 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4647 |  | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 4648 | if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) { | 
|  | 4649 | unsigned opNo = U.getOperandNo(); | 
| Matt Arsenault | 02d915b | 2017-03-15 22:35:20 +0000 | [diff] [blame] | 4650 | if (opNo != StoreInst::getPointerOperandIndex()) | 
|  | 4651 | return true; // Storing addr, not into addr. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4652 | MemoryUses.push_back(std::make_pair(SI, opNo)); | 
|  | 4653 | continue; | 
|  | 4654 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4655 |  | 
| Matt Arsenault | 02d915b | 2017-03-15 22:35:20 +0000 | [diff] [blame] | 4656 | if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(UserI)) { | 
|  | 4657 | unsigned opNo = U.getOperandNo(); | 
|  | 4658 | if (opNo != AtomicRMWInst::getPointerOperandIndex()) | 
|  | 4659 | return true; // Storing addr, not into addr. | 
|  | 4660 | MemoryUses.push_back(std::make_pair(RMW, opNo)); | 
|  | 4661 | continue; | 
|  | 4662 | } | 
|  | 4663 |  | 
|  | 4664 | if (AtomicCmpXchgInst *CmpX = dyn_cast<AtomicCmpXchgInst>(UserI)) { | 
|  | 4665 | unsigned opNo = U.getOperandNo(); | 
|  | 4666 | if (opNo != AtomicCmpXchgInst::getPointerOperandIndex()) | 
|  | 4667 | return true; // Storing addr, not into addr. | 
|  | 4668 | MemoryUses.push_back(std::make_pair(CmpX, opNo)); | 
|  | 4669 | continue; | 
|  | 4670 | } | 
|  | 4671 |  | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 4672 | if (CallInst *CI = dyn_cast<CallInst>(UserI)) { | 
| Matt Arsenault | 23b7609 | 2020-01-31 14:35:53 -0500 | [diff] [blame] | 4673 | if (CI->hasFnAttr(Attribute::Cold)) { | 
|  | 4674 | // If this is a cold call, we can sink the addressing calculation into | 
|  | 4675 | // the cold path.  See optimizeCallInst | 
|  | 4676 | bool OptForSize = OptSize || | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4677 | llvm::shouldOptimizeForSize(CI->getParent(), PSI, BFI); | 
| Matt Arsenault | 23b7609 | 2020-01-31 14:35:53 -0500 | [diff] [blame] | 4678 | if (!OptForSize) | 
|  | 4679 | continue; | 
|  | 4680 | } | 
| Junmo Park | 6098cbb | 2016-03-11 07:05:32 +0000 | [diff] [blame] | 4681 |  | 
| Craig Topper | a58b62b | 2020-04-27 20:15:59 -0700 | [diff] [blame] | 4682 | InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledOperand()); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4683 | if (!IA) return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4684 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4685 | // If this is a memory operand, we're cool, otherwise bail out. | 
| Igor Laevsky | 3be81ba | 2017-02-07 13:27:20 +0000 | [diff] [blame] | 4686 | if (!IsOperandAMemoryOperand(CI, IA, I, TLI, TRI)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4687 | return true; | 
|  | 4688 | continue; | 
|  | 4689 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4690 |  | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4691 | if (FindAllMemoryUses(UserI, MemoryUses, ConsideredInsts, TLI, TRI, OptSize, | 
|  | 4692 | PSI, BFI, SeenInsts)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4693 | return true; | 
|  | 4694 | } | 
|  | 4695 |  | 
|  | 4696 | return false; | 
|  | 4697 | } | 
|  | 4698 |  | 
| Sanjay Patel | 9fbe22b | 2015-10-09 18:01:03 +0000 | [diff] [blame] | 4699 | /// Return true if Val is already known to be live at the use site that we're | 
|  | 4700 | /// folding it into. If so, there is no cost to include it in the addressing | 
|  | 4701 | /// mode. KnownLive1 and KnownLive2 are two values that we know are live at the | 
|  | 4702 | /// instruction already. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4703 | bool AddressingModeMatcher::valueAlreadyLiveAtInst(Value *Val,Value *KnownLive1, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4704 | Value *KnownLive2) { | 
|  | 4705 | // If Val is either of the known-live values, we know it is live! | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4706 | if (Val == nullptr || Val == KnownLive1 || Val == KnownLive2) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4707 | return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4708 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4709 | // All values other than instructions and arguments (e.g. constants) are live. | 
|  | 4710 | if (!isa<Instruction>(Val) && !isa<Argument>(Val)) return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4711 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4712 | // If Val is a constant sized alloca in the entry block, it is live, this is | 
|  | 4713 | // true because it is just a reference to the stack/frame pointer, which is | 
|  | 4714 | // live for the whole function. | 
|  | 4715 | if (AllocaInst *AI = dyn_cast<AllocaInst>(Val)) | 
|  | 4716 | if (AI->isStaticAlloca()) | 
|  | 4717 | return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4718 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4719 | // Check to see if this value is already used in the memory instruction's | 
|  | 4720 | // block.  If so, it's already live into the block at the very least, so we | 
|  | 4721 | // can reasonably fold it. | 
|  | 4722 | return Val->isUsedInBasicBlock(MemoryInst->getParent()); | 
|  | 4723 | } | 
|  | 4724 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4725 | /// It is possible for the addressing mode of the machine to fold the specified | 
|  | 4726 | /// instruction into a load or store that ultimately uses it. | 
|  | 4727 | /// However, the specified instruction has multiple uses. | 
|  | 4728 | /// Given this, it may actually increase register pressure to fold it | 
|  | 4729 | /// into the load. For example, consider this code: | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4730 | /// | 
|  | 4731 | ///     X = ... | 
|  | 4732 | ///     Y = X+1 | 
|  | 4733 | ///     use(Y)   -> nonload/store | 
|  | 4734 | ///     Z = Y+1 | 
|  | 4735 | ///     load Z | 
|  | 4736 | /// | 
|  | 4737 | /// In this case, Y has multiple uses, and can be folded into the load of Z | 
|  | 4738 | /// (yielding load [X+2]).  However, doing this will cause both "X" and "X+1" to | 
|  | 4739 | /// be live at the use(Y) line.  If we don't fold Y into load Z, we use one | 
|  | 4740 | /// fewer register.  Since Y can't be folded into "use(Y)" we don't increase the | 
|  | 4741 | /// number of computations either. | 
|  | 4742 | /// | 
|  | 4743 | /// Note that this (like most of CodeGenPrepare) is just a rough heuristic.  If | 
|  | 4744 | /// X was live across 'load Z' for other reasons, we actually *would* want to | 
|  | 4745 | /// fold the addressing mode in the Z case.  This would make Y die earlier. | 
|  | 4746 | bool AddressingModeMatcher:: | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4747 | isProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore, | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4748 | ExtAddrMode &AMAfter) { | 
|  | 4749 | if (IgnoreProfitability) return true; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4750 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4751 | // AMBefore is the addressing mode before this instruction was folded into it, | 
|  | 4752 | // and AMAfter is the addressing mode after the instruction was folded.  Get | 
|  | 4753 | // the set of registers referenced by AMAfter and subtract out those | 
|  | 4754 | // referenced by AMBefore: this is the set of values which folding in this | 
|  | 4755 | // address extends the lifetime of. | 
|  | 4756 | // | 
|  | 4757 | // Note that there are only two potential values being referenced here, | 
|  | 4758 | // BaseReg and ScaleReg (global addresses are always available, as are any | 
|  | 4759 | // folded immediates). | 
|  | 4760 | Value *BaseReg = AMAfter.BaseReg, *ScaledReg = AMAfter.ScaledReg; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4761 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4762 | // If the BaseReg or ScaledReg was referenced by the previous addrmode, their | 
|  | 4763 | // lifetime wasn't extended by adding this instruction. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4764 | if (valueAlreadyLiveAtInst(BaseReg, AMBefore.BaseReg, AMBefore.ScaledReg)) | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4765 | BaseReg = nullptr; | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4766 | if (valueAlreadyLiveAtInst(ScaledReg, AMBefore.BaseReg, AMBefore.ScaledReg)) | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4767 | ScaledReg = nullptr; | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4768 |  | 
|  | 4769 | // If folding this instruction (and it's subexprs) didn't extend any live | 
|  | 4770 | // ranges, we're ok with it. | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4771 | if (!BaseReg && !ScaledReg) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4772 | return true; | 
|  | 4773 |  | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 4774 | // If all uses of this instruction can have the address mode sunk into them, | 
|  | 4775 | // we can remove the addressing mode and effectively trade one live register | 
|  | 4776 | // for another (at worst.)  In this context, folding an addressing mode into | 
| Junmo Park | 6098cbb | 2016-03-11 07:05:32 +0000 | [diff] [blame] | 4777 | // the use is just a particularly nice way of sinking it. | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4778 | SmallVector<std::pair<Instruction*,unsigned>, 16> MemoryUses; | 
|  | 4779 | SmallPtrSet<Instruction*, 16> ConsideredInsts; | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4780 | if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TLI, TRI, OptSize, | 
|  | 4781 | PSI, BFI)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4782 | return false;  // Has a non-memory, non-foldable use! | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4783 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4784 | // Now that we know that all uses of this instruction are part of a chain of | 
|  | 4785 | // computation involving only operations that could theoretically be folded | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 4786 | // into a memory use, loop over each of these memory operation uses and see | 
|  | 4787 | // if they could  *actually* fold the instruction.  The assumption is that | 
|  | 4788 | // addressing modes are cheap and that duplicating the computation involved | 
|  | 4789 | // many times is worthwhile, even on a fastpath. For sinking candidates | 
|  | 4790 | // (i.e. cold call sites), this serves as a way to prevent excessive code | 
|  | 4791 | // growth since most architectures have some reasonable small and fast way to | 
|  | 4792 | // compute an effective address.  (i.e LEA on x86) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4793 | SmallVector<Instruction*, 32> MatchedAddrModeInsts; | 
|  | 4794 | for (unsigned i = 0, e = MemoryUses.size(); i != e; ++i) { | 
|  | 4795 | Instruction *User = MemoryUses[i].first; | 
|  | 4796 | unsigned OpNo = MemoryUses[i].second; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4797 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4798 | // Get the access type of this use.  If the use isn't a pointer, we don't | 
|  | 4799 | // know what it accesses. | 
|  | 4800 | Value *Address = User->getOperand(OpNo); | 
| Matt Arsenault | f72b49b | 2015-06-04 16:17:38 +0000 | [diff] [blame] | 4801 | PointerType *AddrTy = dyn_cast<PointerType>(Address->getType()); | 
|  | 4802 | if (!AddrTy) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4803 | return false; | 
| Matt Arsenault | f72b49b | 2015-06-04 16:17:38 +0000 | [diff] [blame] | 4804 | Type *AddressAccessTy = AddrTy->getElementType(); | 
|  | 4805 | unsigned AS = AddrTy->getAddressSpace(); | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4806 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4807 | // Do a match against the root of this address, ignoring profitability. This | 
|  | 4808 | // will tell us if the addressing mode for the memory operation will | 
|  | 4809 | // *actually* cover the shared instruction. | 
|  | 4810 | ExtAddrMode Result; | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4811 | std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(nullptr, | 
|  | 4812 | 0); | 
| Quentin Colombet | 5a69dda | 2014-02-11 01:59:02 +0000 | [diff] [blame] | 4813 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 4814 | TPT.getRestorationPoint(); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4815 | AddressingModeMatcher Matcher( | 
|  | 4816 | MatchedAddrModeInsts, TLI, TRI, AddressAccessTy, AS, MemoryInst, Result, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4817 | InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI, BFI); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4818 | Matcher.IgnoreProfitability = true; | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4819 | bool Success = Matcher.matchAddr(Address, 0); | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4820 | (void)Success; assert(Success && "Couldn't select *anything*?"); | 
|  | 4821 |  | 
| Quentin Colombet | 5a69dda | 2014-02-11 01:59:02 +0000 | [diff] [blame] | 4822 | // The match was to check the profitability, the changes made are not | 
|  | 4823 | // part of the original matcher. Therefore, they should be dropped | 
|  | 4824 | // otherwise the original matcher will not present the right state. | 
|  | 4825 | TPT.rollback(LastKnownGood); | 
|  | 4826 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4827 | // If the match didn't cover I, then it won't be shared by it. | 
| David Majnemer | 0d955d0 | 2016-08-11 22:21:41 +0000 | [diff] [blame] | 4828 | if (!is_contained(MatchedAddrModeInsts, I)) | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4829 | return false; | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4830 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4831 | MatchedAddrModeInsts.clear(); | 
|  | 4832 | } | 
| Stephen Lin | 837bba1 | 2013-07-15 17:55:02 +0000 | [diff] [blame] | 4833 |  | 
| Chandler Carruth | c892591 | 2013-01-05 02:09:22 +0000 | [diff] [blame] | 4834 | return true; | 
|  | 4835 | } | 
|  | 4836 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4837 | /// Return true if the specified values are defined in a | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4838 | /// different basic block than BB. | 
|  | 4839 | static bool IsNonLocalValue(Value *V, BasicBlock *BB) { | 
|  | 4840 | if (Instruction *I = dyn_cast<Instruction>(V)) | 
|  | 4841 | return I->getParent() != BB; | 
|  | 4842 | return false; | 
|  | 4843 | } | 
|  | 4844 |  | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 4845 | /// Sink addressing mode computation immediate before MemoryInst if doing so | 
|  | 4846 | /// can be done without increasing register pressure.  The need for the | 
|  | 4847 | /// register pressure constraint means this can end up being an all or nothing | 
|  | 4848 | /// decision for all uses of the same addressing computation. | 
|  | 4849 | /// | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 4850 | /// Load and Store Instructions often have addressing modes that can do | 
|  | 4851 | /// significant amounts of computation. As such, instruction selection will try | 
|  | 4852 | /// to get the load or store to do as much computation as possible for the | 
|  | 4853 | /// program. The problem is that isel can only see within a single block. As | 
|  | 4854 | /// such, we sink as much legal addressing mode work into the block as possible. | 
| Chris Lattner | 728f902 | 2008-11-25 07:09:13 +0000 | [diff] [blame] | 4855 | /// | 
|  | 4856 | /// This method is used to optimize both load/store and inline asms with memory | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 4857 | /// operands.  It's also used to sink addressing computations feeding into cold | 
|  | 4858 | /// call sites into their (cold) basic block. | 
|  | 4859 | /// | 
|  | 4860 | /// The motivation for handling sinking into cold blocks is that doing so can | 
|  | 4861 | /// both enable other address mode sinking (by satisfying the register pressure | 
|  | 4862 | /// constraint above), and reduce register pressure globally (by removing the | 
|  | 4863 | /// addressing mode computation from the fast path entirely.). | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 4864 | bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, | 
| Matt Arsenault | f72b49b | 2015-06-04 16:17:38 +0000 | [diff] [blame] | 4865 | Type *AccessTy, unsigned AddrSpace) { | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4866 | Value *Repl = Addr; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4867 |  | 
|  | 4868 | // Try to collapse single-value PHI nodes.  This is necessary to undo | 
| Owen Anderson | dfb8c3b | 2010-11-19 22:15:03 +0000 | [diff] [blame] | 4869 | // unprofitable PRE transformations. | 
| Cameron Zwarich | 43cecb1 | 2011-01-03 06:33:01 +0000 | [diff] [blame] | 4870 | SmallVector<Value*, 8> worklist; | 
|  | 4871 | SmallPtrSet<Value*, 16> Visited; | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4872 | worklist.push_back(Addr); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4873 |  | 
| John Brawn | eb83c75 | 2017-10-03 13:04:15 +0000 | [diff] [blame] | 4874 | // Use a worklist to iteratively look through PHI and select nodes, and | 
|  | 4875 | // ensure that the addressing mode obtained from the non-PHI/select roots of | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 4876 | // the graph are compatible. | 
| John Brawn | eb83c75 | 2017-10-03 13:04:15 +0000 | [diff] [blame] | 4877 | bool PhiOrSelectSeen = false; | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4878 | SmallVector<Instruction*, 16> AddrModeInsts; | 
| Serguei Katkov | aee6375 | 2017-11-05 07:59:02 +0000 | [diff] [blame] | 4879 | const SimplifyQuery SQ(*DL, TLInfo); | 
| Serguei Katkov | 2673f17 | 2018-11-29 06:45:18 +0000 | [diff] [blame] | 4880 | AddressingModeCombiner AddrModes(SQ, Addr); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 4881 | TypePromotionTransaction TPT(RemovedInsts); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4882 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 4883 | TPT.getRestorationPoint(); | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4884 | while (!worklist.empty()) { | 
|  | 4885 | Value *V = worklist.back(); | 
|  | 4886 | worklist.pop_back(); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4887 |  | 
| Serguei Katkov | 4ea855e | 2017-07-19 04:49:17 +0000 | [diff] [blame] | 4888 | // We allow traversing cyclic Phi nodes. | 
|  | 4889 | // In case of success after this loop we ensure that traversing through | 
|  | 4890 | // Phi nodes ends up with all cases to compute address of the form | 
|  | 4891 | //    BaseGV + Base + Scale * Index + Offset | 
|  | 4892 | // where Scale and Offset are constans and BaseGV, Base and Index | 
|  | 4893 | // are exactly the same Values in all cases. | 
|  | 4894 | // It means that BaseGV, Scale and Offset dominate our memory instruction | 
|  | 4895 | // and have the same value as they had in address computation represented | 
|  | 4896 | // as Phi. So we can safely sink address computation to memory instruction. | 
|  | 4897 | if (!Visited.insert(V).second) | 
|  | 4898 | continue; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4899 |  | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4900 | // For a PHI node, push all of its incoming values. | 
|  | 4901 | if (PHINode *P = dyn_cast<PHINode>(V)) { | 
| Pete Cooper | 833f34d | 2015-05-12 20:05:31 +0000 | [diff] [blame] | 4902 | for (Value *IncValue : P->incoming_values()) | 
|  | 4903 | worklist.push_back(IncValue); | 
| John Brawn | eb83c75 | 2017-10-03 13:04:15 +0000 | [diff] [blame] | 4904 | PhiOrSelectSeen = true; | 
|  | 4905 | continue; | 
|  | 4906 | } | 
|  | 4907 | // Similar for select. | 
|  | 4908 | if (SelectInst *SI = dyn_cast<SelectInst>(V)) { | 
|  | 4909 | worklist.push_back(SI->getFalseValue()); | 
|  | 4910 | worklist.push_back(SI->getTrueValue()); | 
|  | 4911 | PhiOrSelectSeen = true; | 
| Owen Anderson | 8ba5f39 | 2010-11-27 08:15:55 +0000 | [diff] [blame] | 4912 | continue; | 
|  | 4913 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4914 |  | 
| Philip Reames | ac115ed | 2016-03-09 23:13:12 +0000 | [diff] [blame] | 4915 | // For non-PHIs, determine the addressing mode being computed.  Note that | 
|  | 4916 | // the result may differ depending on what other uses our candidate | 
|  | 4917 | // addressing instructions might have. | 
| Serguei Katkov | a6fba3d | 2017-07-18 05:16:38 +0000 | [diff] [blame] | 4918 | AddrModeInsts.clear(); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4919 | std::pair<AssertingVH<GetElementPtrInst>, int64_t> LargeOffsetGEP(nullptr, | 
|  | 4920 | 0); | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4921 | ExtAddrMode NewAddrMode = AddressingModeMatcher::Match( | 
| Serguei Katkov | a6fba3d | 2017-07-18 05:16:38 +0000 | [diff] [blame] | 4922 | V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *TRI, | 
| Hiroshi Yamauchi | d9ae493 | 2019-12-05 09:39:37 -0800 | [diff] [blame] | 4923 | InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI, | 
|  | 4924 | BFI.get()); | 
| Cameron Zwarich | 13c885d | 2011-03-05 08:12:26 +0000 | [diff] [blame] | 4925 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4926 | GetElementPtrInst *GEP = LargeOffsetGEP.first; | 
| Luis Marques | 2e46312 | 2019-06-17 10:54:12 +0000 | [diff] [blame] | 4927 | if (GEP && !NewGEPBases.count(GEP)) { | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 4928 | // If splitting the underlying data structure can reduce the offset of a | 
|  | 4929 | // GEP, collect the GEP.  Skip the GEPs that are the new bases of | 
|  | 4930 | // previously split data structures. | 
|  | 4931 | LargeOffsetGEPMap[GEP->getPointerOperand()].push_back(LargeOffsetGEP); | 
|  | 4932 | if (LargeOffsetGEPID.find(GEP) == LargeOffsetGEPID.end()) | 
|  | 4933 | LargeOffsetGEPID[GEP] = LargeOffsetGEPID.size(); | 
|  | 4934 | } | 
|  | 4935 |  | 
|  | 4936 | NewAddrMode.OriginalValue = V; | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 4937 | if (!AddrModes.addNewAddrMode(NewAddrMode)) | 
|  | 4938 | break; | 
| Owen Anderson | dfb8c3b | 2010-11-19 22:15:03 +0000 | [diff] [blame] | 4939 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4940 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 4941 | // Try to combine the AddrModes we've collected. If we couldn't collect any, | 
|  | 4942 | // or we have multiple but either couldn't combine them or combining them | 
|  | 4943 | // wouldn't do anything useful, bail out now. | 
|  | 4944 | if (!AddrModes.combineAddrModes()) { | 
| Quentin Colombet | 3a4bf04 | 2014-02-06 21:44:56 +0000 | [diff] [blame] | 4945 | TPT.rollback(LastKnownGood); | 
|  | 4946 | return false; | 
|  | 4947 | } | 
|  | 4948 | TPT.commit(); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 4949 |  | 
| John Brawn | 736bf00 | 2017-10-03 13:08:22 +0000 | [diff] [blame] | 4950 | // Get the combined AddrMode (or the only AddrMode, if we only had one). | 
|  | 4951 | ExtAddrMode AddrMode = AddrModes.getAddrMode(); | 
|  | 4952 |  | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4953 | // If all the instructions matched are already in this BB, don't do anything. | 
| John Brawn | eb83c75 | 2017-10-03 13:04:15 +0000 | [diff] [blame] | 4954 | // If we saw a Phi node then it is not local definitely, and if we saw a select | 
|  | 4955 | // then we want to push the address calculation past it even if it's already | 
|  | 4956 | // in this BB. | 
|  | 4957 | if (!PhiOrSelectSeen && none_of(AddrModeInsts, [&](Value *V) { | 
| Justin Lebar | 838c7f5 | 2016-11-21 22:49:11 +0000 | [diff] [blame] | 4958 | return IsNonLocalValue(V, MemoryInst->getParent()); | 
| Serguei Katkov | 0b7b59a | 2017-07-11 06:24:44 +0000 | [diff] [blame] | 4959 | })) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4960 | LLVM_DEBUG(dbgs() << "CGP: Found      local addrmode: " << AddrMode | 
|  | 4961 | << "\n"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4962 | return false; | 
|  | 4963 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 4964 |  | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4965 | // Insert this computation right after this user.  Since our caller is | 
|  | 4966 | // scanning from the top of the BB to the bottom, reuse of the expr are | 
|  | 4967 | // guaranteed to happen later. | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 4968 | IRBuilder<> Builder(MemoryInst); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 4969 |  | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4970 | // Now that we determined the addressing expression we want to use and know | 
|  | 4971 | // that we have to sink it into this block.  Check to see if we have already | 
| Simon Dardis | 230f453 | 2017-11-24 16:45:28 +0000 | [diff] [blame] | 4972 | // done this for some other load/store instr in this block.  If so, reuse | 
|  | 4973 | // the computation.  Before attempting reuse, check if the address is valid | 
|  | 4974 | // as it may have been erased. | 
|  | 4975 |  | 
|  | 4976 | WeakTrackingVH SunkAddrVH = SunkAddrs[Addr]; | 
|  | 4977 |  | 
|  | 4978 | Value * SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4979 | if (SunkAddr) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4980 | LLVM_DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode | 
|  | 4981 | << " for " << *MemoryInst << "\n"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 4982 | if (SunkAddr->getType() != Addr->getType()) | 
| Eli Friedman | c12a5a7 | 2017-02-24 20:51:36 +0000 | [diff] [blame] | 4983 | SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType()); | 
| Tim Northover | 9853484 | 2019-09-12 10:21:00 +0000 | [diff] [blame] | 4984 | } else if (AddrSinkUsingGEPs || (!AddrSinkUsingGEPs.getNumOccurrences() && | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 4985 | SubtargetInfo->addrSinkUsingGEPs())) { | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 4986 | // By default, we use the GEP-based method when AA is used later. This | 
|  | 4987 | // prevents new inttoptr/ptrtoint pairs from degrading AA capabilities. | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 4988 | LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode | 
|  | 4989 | << " for " << *MemoryInst << "\n"); | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 4990 | Type *IntPtrTy = DL->getIntPtrType(Addr->getType()); | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4991 | Value *ResultPtr = nullptr, *ResultIndex = nullptr; | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 4992 |  | 
|  | 4993 | // First, find the pointer. | 
|  | 4994 | if (AddrMode.BaseReg && AddrMode.BaseReg->getType()->isPointerTy()) { | 
|  | 4995 | ResultPtr = AddrMode.BaseReg; | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 4996 | AddrMode.BaseReg = nullptr; | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 4997 | } | 
|  | 4998 |  | 
|  | 4999 | if (AddrMode.Scale && AddrMode.ScaledReg->getType()->isPointerTy()) { | 
|  | 5000 | // We can't add more than one pointer together, nor can we scale a | 
|  | 5001 | // pointer (both of which seem meaningless). | 
|  | 5002 | if (ResultPtr || AddrMode.Scale != 1) | 
|  | 5003 | return false; | 
|  | 5004 |  | 
|  | 5005 | ResultPtr = AddrMode.ScaledReg; | 
|  | 5006 | AddrMode.Scale = 0; | 
|  | 5007 | } | 
|  | 5008 |  | 
| Eli Friedman | 6f7c9ad | 2017-07-12 23:30:02 +0000 | [diff] [blame] | 5009 | // It is only safe to sign extend the BaseReg if we know that the math | 
|  | 5010 | // required to create it did not overflow before we extend it. Since | 
|  | 5011 | // the original IR value was tossed in favor of a constant back when | 
|  | 5012 | // the AddrMode was created we need to bail out gracefully if widths | 
|  | 5013 | // do not match instead of extending it. | 
|  | 5014 | // | 
|  | 5015 | // (See below for code to add the scale.) | 
|  | 5016 | if (AddrMode.Scale) { | 
|  | 5017 | Type *ScaledRegTy = AddrMode.ScaledReg->getType(); | 
|  | 5018 | if (cast<IntegerType>(IntPtrTy)->getBitWidth() > | 
|  | 5019 | cast<IntegerType>(ScaledRegTy)->getBitWidth()) | 
|  | 5020 | return false; | 
|  | 5021 | } | 
|  | 5022 |  | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5023 | if (AddrMode.BaseGV) { | 
|  | 5024 | if (ResultPtr) | 
|  | 5025 | return false; | 
|  | 5026 |  | 
|  | 5027 | ResultPtr = AddrMode.BaseGV; | 
|  | 5028 | } | 
|  | 5029 |  | 
|  | 5030 | // If the real base value actually came from an inttoptr, then the matcher | 
|  | 5031 | // will look through it and provide only the integer value. In that case, | 
|  | 5032 | // use it here. | 
| Keno Fischer | 05e4ac2 | 2017-06-29 20:28:59 +0000 | [diff] [blame] | 5033 | if (!DL->isNonIntegralPointerType(Addr->getType())) { | 
|  | 5034 | if (!ResultPtr && AddrMode.BaseReg) { | 
| David L. Jones | d81f230 | 2019-01-31 03:28:46 +0000 | [diff] [blame] | 5035 | ResultPtr = Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(), | 
|  | 5036 | "sunkaddr"); | 
| Keno Fischer | 05e4ac2 | 2017-06-29 20:28:59 +0000 | [diff] [blame] | 5037 | AddrMode.BaseReg = nullptr; | 
|  | 5038 | } else if (!ResultPtr && AddrMode.Scale == 1) { | 
| David L. Jones | d81f230 | 2019-01-31 03:28:46 +0000 | [diff] [blame] | 5039 | ResultPtr = Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(), | 
|  | 5040 | "sunkaddr"); | 
| Keno Fischer | 05e4ac2 | 2017-06-29 20:28:59 +0000 | [diff] [blame] | 5041 | AddrMode.Scale = 0; | 
|  | 5042 | } | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5043 | } | 
|  | 5044 |  | 
|  | 5045 | if (!ResultPtr && | 
|  | 5046 | !AddrMode.BaseReg && !AddrMode.Scale && !AddrMode.BaseOffs) { | 
|  | 5047 | SunkAddr = Constant::getNullValue(Addr->getType()); | 
|  | 5048 | } else if (!ResultPtr) { | 
|  | 5049 | return false; | 
|  | 5050 | } else { | 
|  | 5051 | Type *I8PtrTy = | 
| David Blaikie | 3909da7 | 2015-03-30 20:42:56 +0000 | [diff] [blame] | 5052 | Builder.getInt8PtrTy(Addr->getType()->getPointerAddressSpace()); | 
|  | 5053 | Type *I8Ty = Builder.getInt8Ty(); | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5054 |  | 
|  | 5055 | // Start with the base register. Do this first so that subsequent address | 
|  | 5056 | // matching finds it last, which will prevent it from trying to match it | 
|  | 5057 | // as the scaled value in case it happens to be a mul. That would be | 
|  | 5058 | // problematic if we've sunk a different mul for the scale, because then | 
|  | 5059 | // we'd end up sinking both muls. | 
|  | 5060 | if (AddrMode.BaseReg) { | 
|  | 5061 | Value *V = AddrMode.BaseReg; | 
|  | 5062 | if (V->getType() != IntPtrTy) | 
|  | 5063 | V = Builder.CreateIntCast(V, IntPtrTy, /*isSigned=*/true, "sunkaddr"); | 
|  | 5064 |  | 
|  | 5065 | ResultIndex = V; | 
|  | 5066 | } | 
|  | 5067 |  | 
|  | 5068 | // Add the scale value. | 
|  | 5069 | if (AddrMode.Scale) { | 
|  | 5070 | Value *V = AddrMode.ScaledReg; | 
|  | 5071 | if (V->getType() == IntPtrTy) { | 
|  | 5072 | // done. | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5073 | } else { | 
| Eli Friedman | 6f7c9ad | 2017-07-12 23:30:02 +0000 | [diff] [blame] | 5074 | assert(cast<IntegerType>(IntPtrTy)->getBitWidth() < | 
|  | 5075 | cast<IntegerType>(V->getType())->getBitWidth() && | 
|  | 5076 | "We can't transform if ScaledReg is too narrow"); | 
|  | 5077 | V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr"); | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5078 | } | 
|  | 5079 |  | 
|  | 5080 | if (AddrMode.Scale != 1) | 
|  | 5081 | V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy, AddrMode.Scale), | 
|  | 5082 | "sunkaddr"); | 
|  | 5083 | if (ResultIndex) | 
|  | 5084 | ResultIndex = Builder.CreateAdd(ResultIndex, V, "sunkaddr"); | 
|  | 5085 | else | 
|  | 5086 | ResultIndex = V; | 
|  | 5087 | } | 
|  | 5088 |  | 
|  | 5089 | // Add in the Base Offset if present. | 
|  | 5090 | if (AddrMode.BaseOffs) { | 
|  | 5091 | Value *V = ConstantInt::get(IntPtrTy, AddrMode.BaseOffs); | 
|  | 5092 | if (ResultIndex) { | 
| NAKAMURA Takumi | f51a34e | 2014-10-29 15:23:11 +0000 | [diff] [blame] | 5093 | // We need to add this separately from the scale above to help with | 
|  | 5094 | // SDAG consecutive load/store merging. | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5095 | if (ResultPtr->getType() != I8PtrTy) | 
| Eli Friedman | c12a5a7 | 2017-02-24 20:51:36 +0000 | [diff] [blame] | 5096 | ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy); | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 5097 | ResultPtr = | 
|  | 5098 | AddrMode.InBounds | 
|  | 5099 | ? Builder.CreateInBoundsGEP(I8Ty, ResultPtr, ResultIndex, | 
|  | 5100 | "sunkaddr") | 
|  | 5101 | : Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr"); | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5102 | } | 
|  | 5103 |  | 
|  | 5104 | ResultIndex = V; | 
|  | 5105 | } | 
|  | 5106 |  | 
|  | 5107 | if (!ResultIndex) { | 
|  | 5108 | SunkAddr = ResultPtr; | 
|  | 5109 | } else { | 
|  | 5110 | if (ResultPtr->getType() != I8PtrTy) | 
| Eli Friedman | c12a5a7 | 2017-02-24 20:51:36 +0000 | [diff] [blame] | 5111 | ResultPtr = Builder.CreatePointerCast(ResultPtr, I8PtrTy); | 
| Tim Northover | 8935aca | 2019-03-12 15:22:23 +0000 | [diff] [blame] | 5112 | SunkAddr = | 
|  | 5113 | AddrMode.InBounds | 
|  | 5114 | ? Builder.CreateInBoundsGEP(I8Ty, ResultPtr, ResultIndex, | 
|  | 5115 | "sunkaddr") | 
|  | 5116 | : Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr"); | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5117 | } | 
|  | 5118 |  | 
|  | 5119 | if (SunkAddr->getType() != Addr->getType()) | 
| Eli Friedman | c12a5a7 | 2017-02-24 20:51:36 +0000 | [diff] [blame] | 5120 | SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType()); | 
| Hal Finkel | c399830 | 2014-04-12 00:59:48 +0000 | [diff] [blame] | 5121 | } | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5122 | } else { | 
| Keno Fischer | 05e4ac2 | 2017-06-29 20:28:59 +0000 | [diff] [blame] | 5123 | // We'd require a ptrtoint/inttoptr down the line, which we can't do for | 
|  | 5124 | // non-integral pointers, so in that case bail out now. | 
|  | 5125 | Type *BaseTy = AddrMode.BaseReg ? AddrMode.BaseReg->getType() : nullptr; | 
|  | 5126 | Type *ScaleTy = AddrMode.Scale ? AddrMode.ScaledReg->getType() : nullptr; | 
|  | 5127 | PointerType *BasePtrTy = dyn_cast_or_null<PointerType>(BaseTy); | 
|  | 5128 | PointerType *ScalePtrTy = dyn_cast_or_null<PointerType>(ScaleTy); | 
|  | 5129 | if (DL->isNonIntegralPointerType(Addr->getType()) || | 
|  | 5130 | (BasePtrTy && DL->isNonIntegralPointerType(BasePtrTy)) || | 
|  | 5131 | (ScalePtrTy && DL->isNonIntegralPointerType(ScalePtrTy)) || | 
|  | 5132 | (AddrMode.BaseGV && | 
|  | 5133 | DL->isNonIntegralPointerType(AddrMode.BaseGV->getType()))) | 
|  | 5134 | return false; | 
|  | 5135 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 5136 | LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode | 
|  | 5137 | << " for " << *MemoryInst << "\n"); | 
| Mehdi Amini | 4fe3798 | 2015-07-07 18:45:17 +0000 | [diff] [blame] | 5138 | Type *IntPtrTy = DL->getIntPtrType(Addr->getType()); | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 5139 | Value *Result = nullptr; | 
| Dan Gohman | ca19445 | 2010-01-19 22:45:06 +0000 | [diff] [blame] | 5140 |  | 
|  | 5141 | // Start with the base register. Do this first so that subsequent address | 
|  | 5142 | // matching finds it last, which will prevent it from trying to match it | 
|  | 5143 | // as the scaled value in case it happens to be a mul. That would be | 
|  | 5144 | // problematic if we've sunk a different mul for the scale, because then | 
|  | 5145 | // we'd end up sinking both muls. | 
|  | 5146 | if (AddrMode.BaseReg) { | 
|  | 5147 | Value *V = AddrMode.BaseReg; | 
| Duncan Sands | 19d0b47 | 2010-02-16 11:11:14 +0000 | [diff] [blame] | 5148 | if (V->getType()->isPointerTy()) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5149 | V = Builder.CreatePtrToInt(V, IntPtrTy, "sunkaddr"); | 
| Dan Gohman | ca19445 | 2010-01-19 22:45:06 +0000 | [diff] [blame] | 5150 | if (V->getType() != IntPtrTy) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5151 | V = Builder.CreateIntCast(V, IntPtrTy, /*isSigned=*/true, "sunkaddr"); | 
| Dan Gohman | ca19445 | 2010-01-19 22:45:06 +0000 | [diff] [blame] | 5152 | Result = V; | 
|  | 5153 | } | 
|  | 5154 |  | 
|  | 5155 | // Add the scale value. | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5156 | if (AddrMode.Scale) { | 
|  | 5157 | Value *V = AddrMode.ScaledReg; | 
|  | 5158 | if (V->getType() == IntPtrTy) { | 
|  | 5159 | // done. | 
| Duncan Sands | 19d0b47 | 2010-02-16 11:11:14 +0000 | [diff] [blame] | 5160 | } else if (V->getType()->isPointerTy()) { | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5161 | V = Builder.CreatePtrToInt(V, IntPtrTy, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5162 | } else if (cast<IntegerType>(IntPtrTy)->getBitWidth() < | 
|  | 5163 | cast<IntegerType>(V->getType())->getBitWidth()) { | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5164 | V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5165 | } else { | 
| Jim Grosbach | ed2cd39 | 2014-03-26 17:27:01 +0000 | [diff] [blame] | 5166 | // It is only safe to sign extend the BaseReg if we know that the math | 
|  | 5167 | // required to create it did not overflow before we extend it. Since | 
|  | 5168 | // the original IR value was tossed in favor of a constant back when | 
|  | 5169 | // the AddrMode was created we need to bail out gracefully if widths | 
|  | 5170 | // do not match instead of extending it. | 
| Joey Gouly | 12a8bf0 | 2014-05-13 15:42:45 +0000 | [diff] [blame] | 5171 | Instruction *I = dyn_cast_or_null<Instruction>(Result); | 
| Jim Grosbach | 83b44e1 | 2014-04-10 00:27:45 +0000 | [diff] [blame] | 5172 | if (I && (Result != AddrMode.BaseReg)) | 
|  | 5173 | I->eraseFromParent(); | 
| Jim Grosbach | ed2cd39 | 2014-03-26 17:27:01 +0000 | [diff] [blame] | 5174 | return false; | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5175 | } | 
|  | 5176 | if (AddrMode.Scale != 1) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5177 | V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy, AddrMode.Scale), | 
|  | 5178 | "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5179 | if (Result) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5180 | Result = Builder.CreateAdd(Result, V, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5181 | else | 
|  | 5182 | Result = V; | 
|  | 5183 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 5184 |  | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5185 | // Add in the BaseGV if present. | 
|  | 5186 | if (AddrMode.BaseGV) { | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5187 | Value *V = Builder.CreatePtrToInt(AddrMode.BaseGV, IntPtrTy, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5188 | if (Result) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5189 | Result = Builder.CreateAdd(Result, V, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5190 | else | 
|  | 5191 | Result = V; | 
|  | 5192 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 5193 |  | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5194 | // Add in the Base Offset if present. | 
|  | 5195 | if (AddrMode.BaseOffs) { | 
| Owen Anderson | edb4a70 | 2009-07-24 23:12:02 +0000 | [diff] [blame] | 5196 | Value *V = ConstantInt::get(IntPtrTy, AddrMode.BaseOffs); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5197 | if (Result) | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5198 | Result = Builder.CreateAdd(Result, V, "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5199 | else | 
|  | 5200 | Result = V; | 
|  | 5201 | } | 
|  | 5202 |  | 
| Craig Topper | c0196b1 | 2014-04-14 00:51:57 +0000 | [diff] [blame] | 5203 | if (!Result) | 
| Owen Anderson | 5a1acd9 | 2009-07-31 20:28:14 +0000 | [diff] [blame] | 5204 | SunkAddr = Constant::getNullValue(Addr->getType()); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5205 | else | 
| Devang Patel | c10e52a | 2011-09-06 18:49:53 +0000 | [diff] [blame] | 5206 | SunkAddr = Builder.CreateIntToPtr(Result, Addr->getType(), "sunkaddr"); | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5207 | } | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 5208 |  | 
| Owen Anderson | dfb8c3b | 2010-11-19 22:15:03 +0000 | [diff] [blame] | 5209 | MemoryInst->replaceUsesOfWith(Repl, SunkAddr); | 
| Simon Dardis | 230f453 | 2017-11-24 16:45:28 +0000 | [diff] [blame] | 5210 | // Store the newly computed address into the cache. In the case we reused a | 
|  | 5211 | // value, this should be idempotent. | 
|  | 5212 | SunkAddrs[Addr] = WeakTrackingVH(SunkAddr); | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 5213 |  | 
| Chris Lattner | af1bcce | 2011-04-09 07:05:44 +0000 | [diff] [blame] | 5214 | // If we have no uses, recursively delete the value and all dead instructions | 
|  | 5215 | // using it. | 
| Owen Anderson | dfb8c3b | 2010-11-19 22:15:03 +0000 | [diff] [blame] | 5216 | if (Repl->use_empty()) { | 
| Chris Lattner | af1bcce | 2011-04-09 07:05:44 +0000 | [diff] [blame] | 5217 | // This can cause recursive deletion, which can invalidate our iterator. | 
| Sanjoy Das | e6bca0e | 2017-05-01 17:07:49 +0000 | [diff] [blame] | 5218 | // Use a WeakTrackingVH to hold onto it in case this happens. | 
| Duncan P. N. Exon Smith | 7b26964 | 2016-02-21 19:37:45 +0000 | [diff] [blame] | 5219 | Value *CurValue = &*CurInstIterator; | 
| Sanjoy Das | e6bca0e | 2017-05-01 17:07:49 +0000 | [diff] [blame] | 5220 | WeakTrackingVH IterHandle(CurValue); | 
| Chris Lattner | af1bcce | 2011-04-09 07:05:44 +0000 | [diff] [blame] | 5221 | BasicBlock *BB = CurInstIterator->getParent(); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 5222 |  | 
| Benjamin Kramer | 8bcc971 | 2012-08-29 15:32:21 +0000 | [diff] [blame] | 5223 | RecursivelyDeleteTriviallyDeadInstructions(Repl, TLInfo); | 
| Chris Lattner | af1bcce | 2011-04-09 07:05:44 +0000 | [diff] [blame] | 5224 |  | 
| Duncan P. N. Exon Smith | 7b26964 | 2016-02-21 19:37:45 +0000 | [diff] [blame] | 5225 | if (IterHandle != CurValue) { | 
| Chris Lattner | af1bcce | 2011-04-09 07:05:44 +0000 | [diff] [blame] | 5226 | // If the iterator instruction was recursively deleted, start over at the | 
|  | 5227 | // start of the block. | 
|  | 5228 | CurInstIterator = BB->begin(); | 
|  | 5229 | SunkAddrs.clear(); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 5230 | } | 
| Dale Johannesen | b67a6e66 | 2010-03-31 20:37:15 +0000 | [diff] [blame] | 5231 | } | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 5232 | ++NumMemoryInsts; | 
| Chris Lattner | feee64e | 2007-04-13 20:30:56 +0000 | [diff] [blame] | 5233 | return true; | 
|  | 5234 | } | 
|  | 5235 |  | 
| Craig Topper | 944cc5e | 2020-04-16 17:03:16 -0700 | [diff] [blame] | 5236 | /// Rewrite GEP input to gather/scatter to enable SelectionDAGBuilder to find | 
|  | 5237 | /// a uniform base to use for ISD::MGATHER/MSCATTER. SelectionDAGBuilder can | 
|  | 5238 | /// only handle a 2 operand GEP in the same basic block or a splat constant | 
|  | 5239 | /// vector. The 2 operands to the GEP must have a scalar pointer and a vector | 
|  | 5240 | /// index. | 
|  | 5241 | /// | 
|  | 5242 | /// If the existing GEP has a vector base pointer that is splat, we can look | 
|  | 5243 | /// through the splat to find the scalar pointer. If we can't find a scalar | 
|  | 5244 | /// pointer there's nothing we can do. | 
|  | 5245 | /// | 
|  | 5246 | /// If we have a GEP with more than 2 indices where the middle indices are all | 
|  | 5247 | /// zeroes, we can replace it with 2 GEPs where the second has 2 operands. | 
|  | 5248 | /// | 
|  | 5249 | /// If the final index isn't a vector or is a splat, we can emit a scalar GEP | 
|  | 5250 | /// followed by a GEP with an all zeroes vector index. This will enable | 
|  | 5251 | /// SelectionDAGBuilder to use a the scalar GEP as the uniform base and have a | 
|  | 5252 | /// zero index. | 
|  | 5253 | bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst, | 
|  | 5254 | Value *Ptr) { | 
|  | 5255 | const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr); | 
|  | 5256 | if (!GEP || !GEP->hasIndices()) | 
|  | 5257 | return false; | 
|  | 5258 |  | 
|  | 5259 | // If the GEP and the gather/scatter aren't in the same BB, don't optimize. | 
|  | 5260 | // FIXME: We should support this by sinking the GEP. | 
|  | 5261 | if (MemoryInst->getParent() != GEP->getParent()) | 
|  | 5262 | return false; | 
|  | 5263 |  | 
|  | 5264 | SmallVector<Value *, 2> Ops(GEP->op_begin(), GEP->op_end()); | 
|  | 5265 |  | 
|  | 5266 | bool RewriteGEP = false; | 
|  | 5267 |  | 
|  | 5268 | if (Ops[0]->getType()->isVectorTy()) { | 
|  | 5269 | Ops[0] = const_cast<Value *>(getSplatValue(Ops[0])); | 
|  | 5270 | if (!Ops[0]) | 
|  | 5271 | return false; | 
|  | 5272 | RewriteGEP = true; | 
|  | 5273 | } | 
|  | 5274 |  | 
|  | 5275 | unsigned FinalIndex = Ops.size() - 1; | 
|  | 5276 |  | 
|  | 5277 | // Ensure all but the last index is 0. | 
|  | 5278 | // FIXME: This isn't strictly required. All that's required is that they are | 
|  | 5279 | // all scalars or splats. | 
|  | 5280 | for (unsigned i = 1; i < FinalIndex; ++i) { | 
|  | 5281 | auto *C = dyn_cast<Constant>(Ops[i]); | 
|  | 5282 | if (!C) | 
|  | 5283 | return false; | 
|  | 5284 | if (isa<VectorType>(C->getType())) | 
|  | 5285 | C = C->getSplatValue(); | 
|  | 5286 | auto *CI = dyn_cast_or_null<ConstantInt>(C); | 
|  | 5287 | if (!CI || !CI->isZero()) | 
|  | 5288 | return false; | 
|  | 5289 | // Scalarize the index if needed. | 
|  | 5290 | Ops[i] = CI; | 
|  | 5291 | } | 
|  | 5292 |  | 
|  | 5293 | // Try to scalarize the final index. | 
|  | 5294 | if (Ops[FinalIndex]->getType()->isVectorTy()) { | 
|  | 5295 | if (Value *V = const_cast<Value *>(getSplatValue(Ops[FinalIndex]))) { | 
|  | 5296 | auto *C = dyn_cast<ConstantInt>(V); | 
|  | 5297 | // Don't scalarize all zeros vector. | 
|  | 5298 | if (!C || !C->isZero()) { | 
|  | 5299 | Ops[FinalIndex] = V; | 
|  | 5300 | RewriteGEP = true; | 
|  | 5301 | } | 
|  | 5302 | } | 
|  | 5303 | } | 
|  | 5304 |  | 
|  | 5305 | // If we made any changes or the we have extra operands, we need to generate | 
|  | 5306 | // new instructions. | 
|  | 5307 | if (!RewriteGEP && Ops.size() == 2) | 
|  | 5308 | return false; | 
|  | 5309 |  | 
| Christopher Tetreault | c858deb | 2020-04-17 13:29:38 -0700 | [diff] [blame] | 5310 | unsigned NumElts = cast<VectorType>(Ptr->getType())->getNumElements(); | 
| Craig Topper | 944cc5e | 2020-04-16 17:03:16 -0700 | [diff] [blame] | 5311 |  | 
|  | 5312 | IRBuilder<> Builder(MemoryInst); | 
|  | 5313 |  | 
|  | 5314 | Type *ScalarIndexTy = DL->getIndexType(Ops[0]->getType()->getScalarType()); | 
|  | 5315 |  | 
|  | 5316 | Value *NewAddr; | 
|  | 5317 |  | 
|  | 5318 | // If the final index isn't a vector, emit a scalar GEP containing all ops | 
|  | 5319 | // and a vector GEP with all zeroes final index. | 
|  | 5320 | if (!Ops[FinalIndex]->getType()->isVectorTy()) { | 
|  | 5321 | NewAddr = Builder.CreateGEP(Ops[0], makeArrayRef(Ops).drop_front()); | 
|  | 5322 | Type *IndexTy = VectorType::get(ScalarIndexTy, NumElts); | 
|  | 5323 | NewAddr = Builder.CreateGEP(NewAddr, Constant::getNullValue(IndexTy)); | 
|  | 5324 | } else { | 
|  | 5325 | Value *Base = Ops[0]; | 
|  | 5326 | Value *Index = Ops[FinalIndex]; | 
|  | 5327 |  | 
|  | 5328 | // Create a scalar GEP if there are more than 2 operands. | 
|  | 5329 | if (Ops.size() != 2) { | 
|  | 5330 | // Replace the last index with 0. | 
|  | 5331 | Ops[FinalIndex] = Constant::getNullValue(ScalarIndexTy); | 
|  | 5332 | Base = Builder.CreateGEP(Base, makeArrayRef(Ops).drop_front()); | 
|  | 5333 | } | 
|  | 5334 |  | 
|  | 5335 | // Now create the GEP with scalar pointer and vector index. | 
|  | 5336 | NewAddr = Builder.CreateGEP(Base, Index); | 
|  | 5337 | } | 
|  | 5338 |  | 
|  | 5339 | MemoryInst->replaceUsesOfWith(Ptr, NewAddr); | 
|  | 5340 |  | 
|  | 5341 | // If we have no uses, recursively delete the value and all dead instructions | 
|  | 5342 | // using it. | 
|  | 5343 | if (Ptr->use_empty()) | 
|  | 5344 | RecursivelyDeleteTriviallyDeadInstructions(Ptr, TLInfo); | 
|  | 5345 |  | 
|  | 5346 | return true; | 
|  | 5347 | } | 
|  | 5348 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 5349 | /// If there are any memory operands, use OptimizeMemoryInst to sink their | 
|  | 5350 | /// address computing into the block when possible / profitable. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 5351 | bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) { | 
| Evan Cheng | 1da2500 | 2008-02-26 02:42:37 +0000 | [diff] [blame] | 5352 | bool MadeChange = false; | 
| Evan Cheng | 1da2500 | 2008-02-26 02:42:37 +0000 | [diff] [blame] | 5353 |  | 
| Eric Christopher | 11e4df7 | 2015-02-26 22:38:43 +0000 | [diff] [blame] | 5354 | const TargetRegisterInfo *TRI = | 
| Sanjay Patel | 4137d51 | 2017-06-07 14:29:52 +0000 | [diff] [blame] | 5355 | TM->getSubtargetImpl(*CS->getFunction())->getRegisterInfo(); | 
| Mehdi Amini | 8ac7a9d | 2015-07-07 19:07:19 +0000 | [diff] [blame] | 5356 | TargetLowering::AsmOperandInfoVector TargetConstraints = | 
| Craig Topper | 95192f5 | 2020-04-11 21:45:09 -0700 | [diff] [blame] | 5357 | TLI->ParseConstraints(*DL, TRI, *CS); | 
| Dale Johannesen | f95f59a | 2010-09-16 18:30:55 +0000 | [diff] [blame] | 5358 | unsigned ArgNo = 0; | 
| John Thompson | 1094c80 | 2010-09-13 18:15:37 +0000 | [diff] [blame] | 5359 | for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) { | 
|  | 5360 | TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i]; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 5361 |  | 
| Evan Cheng | 1da2500 | 2008-02-26 02:42:37 +0000 | [diff] [blame] | 5362 | // Compute the constraint code and ConstraintType to use. | 
| Dale Johannesen | ce97d55 | 2010-06-25 21:55:36 +0000 | [diff] [blame] | 5363 | TLI->ComputeConstraintToUse(OpInfo, SDValue()); | 
| Evan Cheng | 1da2500 | 2008-02-26 02:42:37 +0000 | [diff] [blame] | 5364 |  | 
| Eli Friedman | 666bbe3 | 2008-02-26 18:37:49 +0000 | [diff] [blame] | 5365 | if (OpInfo.ConstraintType == TargetLowering::C_Memory && | 
|  | 5366 | OpInfo.isIndirect) { | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 5367 | Value *OpVal = CS->getArgOperand(ArgNo++); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 5368 | MadeChange |= optimizeMemoryInst(CS, OpVal, OpVal->getType(), ~0u); | 
| Dale Johannesen | f95f59a | 2010-09-16 18:30:55 +0000 | [diff] [blame] | 5369 | } else if (OpInfo.Type == InlineAsm::isInput) | 
|  | 5370 | ArgNo++; | 
| Evan Cheng | 1da2500 | 2008-02-26 02:42:37 +0000 | [diff] [blame] | 5371 | } | 
|  | 5372 |  | 
|  | 5373 | return MadeChange; | 
|  | 5374 | } | 
|  | 5375 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 5376 | /// Check if all the uses of \p Val are equivalent (or free) zero or | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5377 | /// sign extensions. | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5378 | static bool hasSameExtUse(Value *Val, const TargetLowering &TLI) { | 
|  | 5379 | assert(!Val->use_empty() && "Input must have at least one use"); | 
|  | 5380 | const Instruction *FirstUser = cast<Instruction>(*Val->user_begin()); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5381 | bool IsSExt = isa<SExtInst>(FirstUser); | 
|  | 5382 | Type *ExtTy = FirstUser->getType(); | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5383 | for (const User *U : Val->users()) { | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5384 | const Instruction *UI = cast<Instruction>(U); | 
|  | 5385 | if ((IsSExt && !isa<SExtInst>(UI)) || (!IsSExt && !isa<ZExtInst>(UI))) | 
|  | 5386 | return false; | 
|  | 5387 | Type *CurTy = UI->getType(); | 
|  | 5388 | // Same input and output types: Same instruction after CSE. | 
|  | 5389 | if (CurTy == ExtTy) | 
|  | 5390 | continue; | 
|  | 5391 |  | 
|  | 5392 | // If IsSExt is true, we are in this situation: | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5393 | // a = Val | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5394 | // b = sext ty1 a to ty2 | 
|  | 5395 | // c = sext ty1 a to ty3 | 
|  | 5396 | // Assuming ty2 is shorter than ty3, this could be turned into: | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5397 | // a = Val | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5398 | // b = sext ty1 a to ty2 | 
|  | 5399 | // c = sext ty2 b to ty3 | 
|  | 5400 | // However, the last sext is not free. | 
|  | 5401 | if (IsSExt) | 
|  | 5402 | return false; | 
|  | 5403 |  | 
|  | 5404 | // This is a ZExt, maybe this is free to extend from one type to another. | 
|  | 5405 | // In that case, we would not account for a different use. | 
|  | 5406 | Type *NarrowTy; | 
|  | 5407 | Type *LargeTy; | 
|  | 5408 | if (ExtTy->getScalarType()->getIntegerBitWidth() > | 
|  | 5409 | CurTy->getScalarType()->getIntegerBitWidth()) { | 
|  | 5410 | NarrowTy = CurTy; | 
|  | 5411 | LargeTy = ExtTy; | 
|  | 5412 | } else { | 
|  | 5413 | NarrowTy = ExtTy; | 
|  | 5414 | LargeTy = CurTy; | 
|  | 5415 | } | 
|  | 5416 |  | 
|  | 5417 | if (!TLI.isZExtFree(NarrowTy, LargeTy)) | 
|  | 5418 | return false; | 
|  | 5419 | } | 
|  | 5420 | // All uses are the same or can be derived from one another for free. | 
|  | 5421 | return true; | 
|  | 5422 | } | 
|  | 5423 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 5424 | /// Try to speculatively promote extensions in \p Exts and continue | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5425 | /// promoting through newly promoted operands recursively as far as doing so is | 
|  | 5426 | /// profitable. Save extensions profitably moved up, in \p ProfitablyMovedExts. | 
|  | 5427 | /// When some promotion happened, \p TPT contains the proper state to revert | 
|  | 5428 | /// them. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5429 | /// | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5430 | /// \return true if some promotion happened, false otherwise. | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5431 | bool CodeGenPrepare::tryToPromoteExts( | 
|  | 5432 | TypePromotionTransaction &TPT, const SmallVectorImpl<Instruction *> &Exts, | 
|  | 5433 | SmallVectorImpl<Instruction *> &ProfitablyMovedExts, | 
|  | 5434 | unsigned CreatedInstsCost) { | 
|  | 5435 | bool Promoted = false; | 
|  | 5436 |  | 
|  | 5437 | // Iterate over all the extensions to try to promote them. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5438 | for (auto I : Exts) { | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5439 | // Early check if we directly have ext(load). | 
|  | 5440 | if (isa<LoadInst>(I->getOperand(0))) { | 
|  | 5441 | ProfitablyMovedExts.push_back(I); | 
|  | 5442 | continue; | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5443 | } | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5444 |  | 
|  | 5445 | // Check whether or not we want to do any promotion.  The reason we have | 
|  | 5446 | // this check inside the for loop is to catch the case where an extension | 
|  | 5447 | // is directly fed by a load because in such case the extension can be moved | 
|  | 5448 | // up without any promotion on its operands. | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 5449 | if (!TLI->enableExtLdPromotion() || DisableExtLdPromotion) | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5450 | return false; | 
|  | 5451 |  | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5452 | // Get the action to perform the promotion. | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5453 | TypePromotionHelper::Action TPH = | 
|  | 5454 | TypePromotionHelper::getAction(I, InsertedInsts, *TLI, PromotedInsts); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5455 | // Check if we can promote. | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5456 | if (!TPH) { | 
|  | 5457 | // Save the current extension as we cannot move up through its operand. | 
|  | 5458 | ProfitablyMovedExts.push_back(I); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5459 | continue; | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5460 | } | 
|  | 5461 |  | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5462 | // Save the current state. | 
|  | 5463 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
|  | 5464 | TPT.getRestorationPoint(); | 
|  | 5465 | SmallVector<Instruction *, 4> NewExts; | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 5466 | unsigned NewCreatedInstsCost = 0; | 
|  | 5467 | unsigned ExtCost = !TLI->isExtFree(I); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5468 | // Promote. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 5469 | Value *PromotedVal = TPH(I, TPT, PromotedInsts, NewCreatedInstsCost, | 
|  | 5470 | &NewExts, nullptr, *TLI); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5471 | assert(PromotedVal && | 
|  | 5472 | "TypePromotionHelper should have filtered out those cases"); | 
|  | 5473 |  | 
|  | 5474 | // We would be able to merge only one extension in a load. | 
|  | 5475 | // Therefore, if we have more than 1 new extension we heuristically | 
|  | 5476 | // cut this search path, because it means we degrade the code quality. | 
|  | 5477 | // With exactly 2, the transformation is neutral, because we will merge | 
|  | 5478 | // one extension but leave one. However, we optimistically keep going, | 
|  | 5479 | // because the new extension may be removed too. | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 5480 | long long TotalCreatedInstsCost = CreatedInstsCost + NewCreatedInstsCost; | 
| Jun Bum Lim | b99a06b | 2017-01-27 17:16:37 +0000 | [diff] [blame] | 5481 | // FIXME: It would be possible to propagate a negative value instead of | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5482 | // conservatively ceiling it to 0. | 
| Jun Bum Lim | b99a06b | 2017-01-27 17:16:37 +0000 | [diff] [blame] | 5483 | TotalCreatedInstsCost = | 
|  | 5484 | std::max((long long)0, (TotalCreatedInstsCost - ExtCost)); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5485 | if (!StressExtLdPromotion && | 
| Quentin Colombet | 1b274f9 | 2015-03-10 21:48:15 +0000 | [diff] [blame] | 5486 | (TotalCreatedInstsCost > 1 || | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 5487 | !isPromotedInstructionLegal(*TLI, *DL, PromotedVal))) { | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5488 | // This promotion is not profitable, rollback to the previous state, and | 
|  | 5489 | // save the current extension in ProfitablyMovedExts as the latest | 
|  | 5490 | // speculative promotion turned out to be unprofitable. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5491 | TPT.rollback(LastKnownGood); | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5492 | ProfitablyMovedExts.push_back(I); | 
|  | 5493 | continue; | 
|  | 5494 | } | 
|  | 5495 | // Continue promoting NewExts as far as doing so is profitable. | 
|  | 5496 | SmallVector<Instruction *, 2> NewlyMovedExts; | 
|  | 5497 | (void)tryToPromoteExts(TPT, NewExts, NewlyMovedExts, TotalCreatedInstsCost); | 
|  | 5498 | bool NewPromoted = false; | 
|  | 5499 | for (auto ExtInst : NewlyMovedExts) { | 
|  | 5500 | Instruction *MovedExt = cast<Instruction>(ExtInst); | 
|  | 5501 | Value *ExtOperand = MovedExt->getOperand(0); | 
|  | 5502 | // If we have reached to a load, we need this extra profitability check | 
|  | 5503 | // as it could potentially be merged into an ext(load). | 
|  | 5504 | if (isa<LoadInst>(ExtOperand) && | 
|  | 5505 | !(StressExtLdPromotion || NewCreatedInstsCost <= ExtCost || | 
|  | 5506 | (ExtOperand->hasOneUse() || hasSameExtUse(ExtOperand, *TLI)))) | 
|  | 5507 | continue; | 
|  | 5508 |  | 
|  | 5509 | ProfitablyMovedExts.push_back(MovedExt); | 
|  | 5510 | NewPromoted = true; | 
|  | 5511 | } | 
|  | 5512 |  | 
|  | 5513 | // If none of speculative promotions for NewExts is profitable, rollback | 
|  | 5514 | // and save the current extension (I) as the last profitable extension. | 
|  | 5515 | if (!NewPromoted) { | 
|  | 5516 | TPT.rollback(LastKnownGood); | 
|  | 5517 | ProfitablyMovedExts.push_back(I); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5518 | continue; | 
|  | 5519 | } | 
|  | 5520 | // The promotion is profitable. | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5521 | Promoted = true; | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5522 | } | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5523 | return Promoted; | 
|  | 5524 | } | 
|  | 5525 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5526 | /// Merging redundant sexts when one is dominating the other. | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 5527 | bool CodeGenPrepare::mergeSExts(Function &F) { | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5528 | bool Changed = false; | 
|  | 5529 | for (auto &Entry : ValToSExtendedUses) { | 
|  | 5530 | SExts &Insts = Entry.second; | 
|  | 5531 | SExts CurPts; | 
|  | 5532 | for (Instruction *Inst : Insts) { | 
|  | 5533 | if (RemovedInsts.count(Inst) || !isa<SExtInst>(Inst) || | 
|  | 5534 | Inst->getOperand(0) != Entry.first) | 
|  | 5535 | continue; | 
|  | 5536 | bool inserted = false; | 
|  | 5537 | for (auto &Pt : CurPts) { | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 5538 | if (getDT(F).dominates(Inst, Pt)) { | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5539 | Pt->replaceAllUsesWith(Inst); | 
|  | 5540 | RemovedInsts.insert(Pt); | 
|  | 5541 | Pt->removeFromParent(); | 
|  | 5542 | Pt = Inst; | 
|  | 5543 | inserted = true; | 
|  | 5544 | Changed = true; | 
|  | 5545 | break; | 
|  | 5546 | } | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 5547 | if (!getDT(F).dominates(Pt, Inst)) | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5548 | // Give up if we need to merge in a common dominator as the | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 5549 | // experiments show it is not profitable. | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5550 | continue; | 
|  | 5551 | Inst->replaceAllUsesWith(Pt); | 
|  | 5552 | RemovedInsts.insert(Inst); | 
|  | 5553 | Inst->removeFromParent(); | 
|  | 5554 | inserted = true; | 
|  | 5555 | Changed = true; | 
|  | 5556 | break; | 
|  | 5557 | } | 
|  | 5558 | if (!inserted) | 
|  | 5559 | CurPts.push_back(Inst); | 
|  | 5560 | } | 
|  | 5561 | } | 
|  | 5562 | return Changed; | 
|  | 5563 | } | 
|  | 5564 |  | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 5565 | // Spliting large data structures so that the GEPs accessing them can have | 
|  | 5566 | // smaller offsets so that they can be sunk to the same blocks as their users. | 
|  | 5567 | // For example, a large struct starting from %base is splitted into two parts | 
|  | 5568 | // where the second part starts from %new_base. | 
|  | 5569 | // | 
|  | 5570 | // Before: | 
|  | 5571 | // BB0: | 
|  | 5572 | //   %base     = | 
|  | 5573 | // | 
|  | 5574 | // BB1: | 
|  | 5575 | //   %gep0     = gep %base, off0 | 
|  | 5576 | //   %gep1     = gep %base, off1 | 
|  | 5577 | //   %gep2     = gep %base, off2 | 
|  | 5578 | // | 
|  | 5579 | // BB2: | 
|  | 5580 | //   %load1    = load %gep0 | 
|  | 5581 | //   %load2    = load %gep1 | 
|  | 5582 | //   %load3    = load %gep2 | 
|  | 5583 | // | 
|  | 5584 | // After: | 
|  | 5585 | // BB0: | 
|  | 5586 | //   %base     = | 
|  | 5587 | //   %new_base = gep %base, off0 | 
|  | 5588 | // | 
|  | 5589 | // BB1: | 
|  | 5590 | //   %new_gep0 = %new_base | 
|  | 5591 | //   %new_gep1 = gep %new_base, off1 - off0 | 
|  | 5592 | //   %new_gep2 = gep %new_base, off2 - off0 | 
|  | 5593 | // | 
|  | 5594 | // BB2: | 
|  | 5595 | //   %load1    = load i32, i32* %new_gep0 | 
|  | 5596 | //   %load2    = load i32, i32* %new_gep1 | 
|  | 5597 | //   %load3    = load i32, i32* %new_gep2 | 
|  | 5598 | // | 
|  | 5599 | // %new_gep1 and %new_gep2 can be sunk to BB2 now after the splitting because | 
|  | 5600 | // their offsets are smaller enough to fit into the addressing mode. | 
|  | 5601 | bool CodeGenPrepare::splitLargeGEPOffsets() { | 
|  | 5602 | bool Changed = false; | 
|  | 5603 | for (auto &Entry : LargeOffsetGEPMap) { | 
|  | 5604 | Value *OldBase = Entry.first; | 
|  | 5605 | SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>> | 
|  | 5606 | &LargeOffsetGEPs = Entry.second; | 
|  | 5607 | auto compareGEPOffset = | 
|  | 5608 | [&](const std::pair<GetElementPtrInst *, int64_t> &LHS, | 
|  | 5609 | const std::pair<GetElementPtrInst *, int64_t> &RHS) { | 
|  | 5610 | if (LHS.first == RHS.first) | 
|  | 5611 | return false; | 
|  | 5612 | if (LHS.second != RHS.second) | 
|  | 5613 | return LHS.second < RHS.second; | 
|  | 5614 | return LargeOffsetGEPID[LHS.first] < LargeOffsetGEPID[RHS.first]; | 
|  | 5615 | }; | 
|  | 5616 | // Sorting all the GEPs of the same data structures based on the offsets. | 
| Fangrui Song | 0cac726 | 2018-09-27 02:13:45 +0000 | [diff] [blame] | 5617 | llvm::sort(LargeOffsetGEPs, compareGEPOffset); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 5618 | LargeOffsetGEPs.erase( | 
|  | 5619 | std::unique(LargeOffsetGEPs.begin(), LargeOffsetGEPs.end()), | 
|  | 5620 | LargeOffsetGEPs.end()); | 
|  | 5621 | // Skip if all the GEPs have the same offsets. | 
|  | 5622 | if (LargeOffsetGEPs.front().second == LargeOffsetGEPs.back().second) | 
|  | 5623 | continue; | 
|  | 5624 | GetElementPtrInst *BaseGEP = LargeOffsetGEPs.begin()->first; | 
|  | 5625 | int64_t BaseOffset = LargeOffsetGEPs.begin()->second; | 
|  | 5626 | Value *NewBaseGEP = nullptr; | 
|  | 5627 |  | 
|  | 5628 | auto LargeOffsetGEP = LargeOffsetGEPs.begin(); | 
|  | 5629 | while (LargeOffsetGEP != LargeOffsetGEPs.end()) { | 
|  | 5630 | GetElementPtrInst *GEP = LargeOffsetGEP->first; | 
|  | 5631 | int64_t Offset = LargeOffsetGEP->second; | 
|  | 5632 | if (Offset != BaseOffset) { | 
|  | 5633 | TargetLowering::AddrMode AddrMode; | 
|  | 5634 | AddrMode.BaseOffs = Offset - BaseOffset; | 
|  | 5635 | // The result type of the GEP might not be the type of the memory | 
|  | 5636 | // access. | 
|  | 5637 | if (!TLI->isLegalAddressingMode(*DL, AddrMode, | 
|  | 5638 | GEP->getResultElementType(), | 
|  | 5639 | GEP->getAddressSpace())) { | 
|  | 5640 | // We need to create a new base if the offset to the current base is | 
|  | 5641 | // too large to fit into the addressing mode. So, a very large struct | 
|  | 5642 | // may be splitted into several parts. | 
|  | 5643 | BaseGEP = GEP; | 
|  | 5644 | BaseOffset = Offset; | 
|  | 5645 | NewBaseGEP = nullptr; | 
|  | 5646 | } | 
|  | 5647 | } | 
|  | 5648 |  | 
|  | 5649 | // Generate a new GEP to replace the current one. | 
| Eli Friedman | a69084f | 2018-12-19 22:52:04 +0000 | [diff] [blame] | 5650 | LLVMContext &Ctx = GEP->getContext(); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 5651 | Type *IntPtrTy = DL->getIntPtrType(GEP->getType()); | 
|  | 5652 | Type *I8PtrTy = | 
| Eli Friedman | a69084f | 2018-12-19 22:52:04 +0000 | [diff] [blame] | 5653 | Type::getInt8PtrTy(Ctx, GEP->getType()->getPointerAddressSpace()); | 
|  | 5654 | Type *I8Ty = Type::getInt8Ty(Ctx); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 5655 |  | 
|  | 5656 | if (!NewBaseGEP) { | 
|  | 5657 | // Create a new base if we don't have one yet.  Find the insertion | 
|  | 5658 | // pointer for the new base first. | 
|  | 5659 | BasicBlock::iterator NewBaseInsertPt; | 
|  | 5660 | BasicBlock *NewBaseInsertBB; | 
|  | 5661 | if (auto *BaseI = dyn_cast<Instruction>(OldBase)) { | 
|  | 5662 | // If the base of the struct is an instruction, the new base will be | 
|  | 5663 | // inserted close to it. | 
|  | 5664 | NewBaseInsertBB = BaseI->getParent(); | 
|  | 5665 | if (isa<PHINode>(BaseI)) | 
|  | 5666 | NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt(); | 
|  | 5667 | else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(BaseI)) { | 
|  | 5668 | NewBaseInsertBB = | 
|  | 5669 | SplitEdge(NewBaseInsertBB, Invoke->getNormalDest()); | 
|  | 5670 | NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt(); | 
|  | 5671 | } else | 
|  | 5672 | NewBaseInsertPt = std::next(BaseI->getIterator()); | 
|  | 5673 | } else { | 
|  | 5674 | // If the current base is an argument or global value, the new base | 
|  | 5675 | // will be inserted to the entry block. | 
|  | 5676 | NewBaseInsertBB = &BaseGEP->getFunction()->getEntryBlock(); | 
|  | 5677 | NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt(); | 
|  | 5678 | } | 
|  | 5679 | IRBuilder<> NewBaseBuilder(NewBaseInsertBB, NewBaseInsertPt); | 
|  | 5680 | // Create a new base. | 
|  | 5681 | Value *BaseIndex = ConstantInt::get(IntPtrTy, BaseOffset); | 
|  | 5682 | NewBaseGEP = OldBase; | 
|  | 5683 | if (NewBaseGEP->getType() != I8PtrTy) | 
|  | 5684 | NewBaseGEP = NewBaseBuilder.CreatePointerCast(NewBaseGEP, I8PtrTy); | 
|  | 5685 | NewBaseGEP = | 
|  | 5686 | NewBaseBuilder.CreateGEP(I8Ty, NewBaseGEP, BaseIndex, "splitgep"); | 
|  | 5687 | NewGEPBases.insert(NewBaseGEP); | 
|  | 5688 | } | 
|  | 5689 |  | 
| Eli Friedman | a69084f | 2018-12-19 22:52:04 +0000 | [diff] [blame] | 5690 | IRBuilder<> Builder(GEP); | 
| Haicheng Wu | 0aae2bc | 2018-05-10 18:27:36 +0000 | [diff] [blame] | 5691 | Value *NewGEP = NewBaseGEP; | 
|  | 5692 | if (Offset == BaseOffset) { | 
|  | 5693 | if (GEP->getType() != I8PtrTy) | 
|  | 5694 | NewGEP = Builder.CreatePointerCast(NewGEP, GEP->getType()); | 
|  | 5695 | } else { | 
|  | 5696 | // Calculate the new offset for the new GEP. | 
|  | 5697 | Value *Index = ConstantInt::get(IntPtrTy, Offset - BaseOffset); | 
|  | 5698 | NewGEP = Builder.CreateGEP(I8Ty, NewBaseGEP, Index); | 
|  | 5699 |  | 
|  | 5700 | if (GEP->getType() != I8PtrTy) | 
|  | 5701 | NewGEP = Builder.CreatePointerCast(NewGEP, GEP->getType()); | 
|  | 5702 | } | 
|  | 5703 | GEP->replaceAllUsesWith(NewGEP); | 
|  | 5704 | LargeOffsetGEPID.erase(GEP); | 
|  | 5705 | LargeOffsetGEP = LargeOffsetGEPs.erase(LargeOffsetGEP); | 
|  | 5706 | GEP->eraseFromParent(); | 
|  | 5707 | Changed = true; | 
|  | 5708 | } | 
|  | 5709 | } | 
|  | 5710 | return Changed; | 
|  | 5711 | } | 
|  | 5712 |  | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5713 | /// Return true, if an ext(load) can be formed from an extension in | 
|  | 5714 | /// \p MovedExts. | 
|  | 5715 | bool CodeGenPrepare::canFormExtLd( | 
|  | 5716 | const SmallVectorImpl<Instruction *> &MovedExts, LoadInst *&LI, | 
|  | 5717 | Instruction *&Inst, bool HasPromoted) { | 
|  | 5718 | for (auto *MovedExtInst : MovedExts) { | 
|  | 5719 | if (isa<LoadInst>(MovedExtInst->getOperand(0))) { | 
|  | 5720 | LI = cast<LoadInst>(MovedExtInst->getOperand(0)); | 
|  | 5721 | Inst = MovedExtInst; | 
|  | 5722 | break; | 
|  | 5723 | } | 
|  | 5724 | } | 
|  | 5725 | if (!LI) | 
|  | 5726 | return false; | 
|  | 5727 |  | 
|  | 5728 | // If they're already in the same block, there's nothing to do. | 
|  | 5729 | // Make the cheap checks first if we did not promote. | 
|  | 5730 | // If we promoted, we need to check if it is indeed profitable. | 
|  | 5731 | if (!HasPromoted && LI->getParent() == Inst->getParent()) | 
|  | 5732 | return false; | 
|  | 5733 |  | 
| Haicheng Wu | abdef9e | 2017-07-15 02:12:16 +0000 | [diff] [blame] | 5734 | return TLI->isExtLoad(LI, Inst, *DL); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5735 | } | 
|  | 5736 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 5737 | /// Move a zext or sext fed by a load into the same basic block as the load, | 
|  | 5738 | /// unless conditions are unfavorable. This allows SelectionDAG to fold the | 
|  | 5739 | /// extend into the load. | 
| Dan Gohman | 99429a0 | 2009-10-16 20:59:35 +0000 | [diff] [blame] | 5740 | /// | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5741 | /// E.g., | 
|  | 5742 | /// \code | 
|  | 5743 | /// %ld = load i32* %addr | 
|  | 5744 | /// %add = add nuw i32 %ld, 4 | 
|  | 5745 | /// %zext = zext i32 %add to i64 | 
|  | 5746 | // \endcode | 
|  | 5747 | /// => | 
|  | 5748 | /// \code | 
|  | 5749 | /// %ld = load i32* %addr | 
|  | 5750 | /// %zext = zext i32 %ld to i64 | 
|  | 5751 | /// %add = add nuw i64 %zext, 4 | 
|  | 5752 | /// \encode | 
|  | 5753 | /// Note that the promotion in %add to i64 is done in tryToPromoteExts(), which | 
|  | 5754 | /// allow us to match zext(load i32*) to i64. | 
|  | 5755 | /// | 
|  | 5756 | /// Also, try to promote the computations used to obtain a sign extended | 
|  | 5757 | /// value used into memory accesses. | 
|  | 5758 | /// E.g., | 
|  | 5759 | /// \code | 
|  | 5760 | /// a = add nsw i32 b, 3 | 
|  | 5761 | /// d = sext i32 a to i64 | 
|  | 5762 | /// e = getelementptr ..., i64 d | 
|  | 5763 | /// \endcode | 
|  | 5764 | /// => | 
|  | 5765 | /// \code | 
|  | 5766 | /// f = sext i32 b to i64 | 
|  | 5767 | /// a = add nsw i64 f, 3 | 
|  | 5768 | /// e = getelementptr ..., i64 a | 
|  | 5769 | /// \endcode | 
|  | 5770 | /// | 
|  | 5771 | /// \p Inst[in/out] the extension may be modified during the process if some | 
|  | 5772 | /// promotions apply. | 
|  | 5773 | bool CodeGenPrepare::optimizeExt(Instruction *&Inst) { | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5774 | bool AllowPromotionWithoutCommonHeader = false; | 
|  | 5775 | /// See if it is an interesting sext operations for the address type | 
|  | 5776 | /// promotion before trying to promote it, e.g., the ones with the right | 
|  | 5777 | /// type and used in memory accesses. | 
|  | 5778 | bool ATPConsiderable = TTI->shouldConsiderAddressTypePromotion( | 
|  | 5779 | *Inst, AllowPromotionWithoutCommonHeader); | 
|  | 5780 | TypePromotionTransaction TPT(RemovedInsts); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5781 | TypePromotionTransaction::ConstRestorationPt LastKnownGood = | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5782 | TPT.getRestorationPoint(); | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5783 | SmallVector<Instruction *, 1> Exts; | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5784 | SmallVector<Instruction *, 2> SpeculativelyMovedExts; | 
|  | 5785 | Exts.push_back(Inst); | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5786 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5787 | bool HasPromoted = tryToPromoteExts(TPT, Exts, SpeculativelyMovedExts); | 
| Jun Bum Lim | 4230101 | 2017-03-17 19:05:21 +0000 | [diff] [blame] | 5788 |  | 
| Dan Gohman | 99429a0 | 2009-10-16 20:59:35 +0000 | [diff] [blame] | 5789 | // Look for a load being extended. | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5790 | LoadInst *LI = nullptr; | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5791 | Instruction *ExtFedByLoad; | 
|  | 5792 |  | 
|  | 5793 | // Try to promote a chain of computation if it allows to form an extended | 
|  | 5794 | // load. | 
|  | 5795 | if (canFormExtLd(SpeculativelyMovedExts, LI, ExtFedByLoad, HasPromoted)) { | 
|  | 5796 | assert(LI && ExtFedByLoad && "Expect a valid load and extension"); | 
|  | 5797 | TPT.commit(); | 
|  | 5798 | // Move the extend into the same block as the load | 
| Sanjay Patel | 674d2c2 | 2017-08-29 14:07:48 +0000 | [diff] [blame] | 5799 | ExtFedByLoad->moveAfter(LI); | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5800 | // CGP does not check if the zext would be speculatively executed when moved | 
|  | 5801 | // to the same basic block as the load. Preserving its original location | 
|  | 5802 | // would pessimize the debugging experience, as well as negatively impact | 
|  | 5803 | // the quality of sample pgo. We don't want to use "line 0" as that has a | 
|  | 5804 | // size cost in the line-table section and logically the zext can be seen as | 
|  | 5805 | // part of the load. Therefore we conservatively reuse the same debug | 
|  | 5806 | // location for the load and the zext. | 
|  | 5807 | ExtFedByLoad->setDebugLoc(LI->getDebugLoc()); | 
|  | 5808 | ++NumExtsMoved; | 
|  | 5809 | Inst = ExtFedByLoad; | 
|  | 5810 | return true; | 
|  | 5811 | } | 
|  | 5812 |  | 
|  | 5813 | // Continue promoting SExts if known as considerable depending on targets. | 
|  | 5814 | if (ATPConsiderable && | 
|  | 5815 | performAddressTypePromotion(Inst, AllowPromotionWithoutCommonHeader, | 
|  | 5816 | HasPromoted, TPT, SpeculativelyMovedExts)) | 
|  | 5817 | return true; | 
|  | 5818 |  | 
|  | 5819 | TPT.rollback(LastKnownGood); | 
|  | 5820 | return false; | 
|  | 5821 | } | 
|  | 5822 |  | 
|  | 5823 | // Perform address type promotion if doing so is profitable. | 
|  | 5824 | // If AllowPromotionWithoutCommonHeader == false, we should find other sext | 
|  | 5825 | // instructions that sign extended the same initial value. However, if | 
|  | 5826 | // AllowPromotionWithoutCommonHeader == true, we expect promoting the | 
|  | 5827 | // extension is just profitable. | 
|  | 5828 | bool CodeGenPrepare::performAddressTypePromotion( | 
|  | 5829 | Instruction *&Inst, bool AllowPromotionWithoutCommonHeader, | 
|  | 5830 | bool HasPromoted, TypePromotionTransaction &TPT, | 
|  | 5831 | SmallVectorImpl<Instruction *> &SpeculativelyMovedExts) { | 
|  | 5832 | bool Promoted = false; | 
|  | 5833 | SmallPtrSet<Instruction *, 1> UnhandledExts; | 
|  | 5834 | bool AllSeenFirst = true; | 
|  | 5835 | for (auto I : SpeculativelyMovedExts) { | 
|  | 5836 | Value *HeadOfChain = I->getOperand(0); | 
|  | 5837 | DenseMap<Value *, Instruction *>::iterator AlreadySeen = | 
|  | 5838 | SeenChainsForSExt.find(HeadOfChain); | 
|  | 5839 | // If there is an unhandled SExt which has the same header, try to promote | 
|  | 5840 | // it as well. | 
|  | 5841 | if (AlreadySeen != SeenChainsForSExt.end()) { | 
|  | 5842 | if (AlreadySeen->second != nullptr) | 
|  | 5843 | UnhandledExts.insert(AlreadySeen->second); | 
|  | 5844 | AllSeenFirst = false; | 
|  | 5845 | } | 
|  | 5846 | } | 
|  | 5847 |  | 
|  | 5848 | if (!AllSeenFirst || (AllowPromotionWithoutCommonHeader && | 
|  | 5849 | SpeculativelyMovedExts.size() == 1)) { | 
|  | 5850 | TPT.commit(); | 
|  | 5851 | if (HasPromoted) | 
|  | 5852 | Promoted = true; | 
|  | 5853 | for (auto I : SpeculativelyMovedExts) { | 
|  | 5854 | Value *HeadOfChain = I->getOperand(0); | 
|  | 5855 | SeenChainsForSExt[HeadOfChain] = nullptr; | 
|  | 5856 | ValToSExtendedUses[HeadOfChain].push_back(I); | 
|  | 5857 | } | 
|  | 5858 | // Update Inst as promotion happen. | 
|  | 5859 | Inst = SpeculativelyMovedExts.pop_back_val(); | 
|  | 5860 | } else { | 
|  | 5861 | // This is the first chain visited from the header, keep the current chain | 
|  | 5862 | // as unhandled. Defer to promote this until we encounter another SExt | 
|  | 5863 | // chain derived from the same header. | 
|  | 5864 | for (auto I : SpeculativelyMovedExts) { | 
|  | 5865 | Value *HeadOfChain = I->getOperand(0); | 
|  | 5866 | SeenChainsForSExt[HeadOfChain] = Inst; | 
|  | 5867 | } | 
| Dan Gohman | 99429a0 | 2009-10-16 20:59:35 +0000 | [diff] [blame] | 5868 | return false; | 
| Quentin Colombet | fc2201e | 2014-12-17 01:36:17 +0000 | [diff] [blame] | 5869 | } | 
| Dan Gohman | 99429a0 | 2009-10-16 20:59:35 +0000 | [diff] [blame] | 5870 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 5871 | if (!AllSeenFirst && !UnhandledExts.empty()) | 
|  | 5872 | for (auto VisitedSExt : UnhandledExts) { | 
|  | 5873 | if (RemovedInsts.count(VisitedSExt)) | 
|  | 5874 | continue; | 
|  | 5875 | TypePromotionTransaction TPT(RemovedInsts); | 
|  | 5876 | SmallVector<Instruction *, 1> Exts; | 
|  | 5877 | SmallVector<Instruction *, 2> Chains; | 
|  | 5878 | Exts.push_back(VisitedSExt); | 
|  | 5879 | bool HasPromoted = tryToPromoteExts(TPT, Exts, Chains); | 
|  | 5880 | TPT.commit(); | 
|  | 5881 | if (HasPromoted) | 
|  | 5882 | Promoted = true; | 
|  | 5883 | for (auto I : Chains) { | 
|  | 5884 | Value *HeadOfChain = I->getOperand(0); | 
|  | 5885 | // Mark this as handled. | 
|  | 5886 | SeenChainsForSExt[HeadOfChain] = nullptr; | 
|  | 5887 | ValToSExtendedUses[HeadOfChain].push_back(I); | 
|  | 5888 | } | 
|  | 5889 | } | 
|  | 5890 | return Promoted; | 
| Dan Gohman | 99429a0 | 2009-10-16 20:59:35 +0000 | [diff] [blame] | 5891 | } | 
|  | 5892 |  | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 5893 | bool CodeGenPrepare::optimizeExtUses(Instruction *I) { | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5894 | BasicBlock *DefBB = I->getParent(); | 
|  | 5895 |  | 
| Bob Wilson | ff714f9 | 2010-09-21 21:44:14 +0000 | [diff] [blame] | 5896 | // If the result of a {s|z}ext and its source are both live out, rewrite all | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5897 | // other uses of the source with result of extension. | 
|  | 5898 | Value *Src = I->getOperand(0); | 
|  | 5899 | if (Src->hasOneUse()) | 
|  | 5900 | return false; | 
|  | 5901 |  | 
| Evan Cheng | 2011df4 | 2007-12-13 07:50:36 +0000 | [diff] [blame] | 5902 | // Only do this xform if truncating is free. | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 5903 | if (!TLI->isTruncateFree(I->getType(), Src->getType())) | 
| Evan Cheng | 37c36ed | 2007-12-13 03:32:53 +0000 | [diff] [blame] | 5904 | return false; | 
|  | 5905 |  | 
| Evan Cheng | 7bc8942 | 2007-12-12 00:51:06 +0000 | [diff] [blame] | 5906 | // Only safe to perform the optimization if the source is also defined in | 
| Evan Cheng | 63d33cf | 2007-12-12 02:53:41 +0000 | [diff] [blame] | 5907 | // this block. | 
|  | 5908 | if (!isa<Instruction>(Src) || DefBB != cast<Instruction>(Src)->getParent()) | 
| Evan Cheng | 7bc8942 | 2007-12-12 00:51:06 +0000 | [diff] [blame] | 5909 | return false; | 
|  | 5910 |  | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5911 | bool DefIsLiveOut = false; | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5912 | for (User *U : I->users()) { | 
|  | 5913 | Instruction *UI = cast<Instruction>(U); | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5914 |  | 
|  | 5915 | // Figure out which BB this ext is used in. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5916 | BasicBlock *UserBB = UI->getParent(); | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5917 | if (UserBB == DefBB) continue; | 
|  | 5918 | DefIsLiveOut = true; | 
|  | 5919 | break; | 
|  | 5920 | } | 
|  | 5921 | if (!DefIsLiveOut) | 
|  | 5922 | return false; | 
|  | 5923 |  | 
| Jim Grosbach | 0f38c1e | 2013-04-15 17:40:48 +0000 | [diff] [blame] | 5924 | // Make sure none of the uses are PHI nodes. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5925 | for (User *U : Src->users()) { | 
|  | 5926 | Instruction *UI = cast<Instruction>(U); | 
|  | 5927 | BasicBlock *UserBB = UI->getParent(); | 
| Evan Cheng | 37c36ed | 2007-12-13 03:32:53 +0000 | [diff] [blame] | 5928 | if (UserBB == DefBB) continue; | 
|  | 5929 | // Be conservative. We don't want this xform to end up introducing | 
|  | 5930 | // reloads just before load / store instructions. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5931 | if (isa<PHINode>(UI) || isa<LoadInst>(UI) || isa<StoreInst>(UI)) | 
| Evan Cheng | 63d33cf | 2007-12-12 02:53:41 +0000 | [diff] [blame] | 5932 | return false; | 
|  | 5933 | } | 
|  | 5934 |  | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5935 | // InsertedTruncs - Only insert one trunc in each block once. | 
|  | 5936 | DenseMap<BasicBlock*, Instruction*> InsertedTruncs; | 
|  | 5937 |  | 
|  | 5938 | bool MadeChange = false; | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5939 | for (Use &U : Src->uses()) { | 
|  | 5940 | Instruction *User = cast<Instruction>(U.getUser()); | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5941 |  | 
|  | 5942 | // Figure out which BB this ext is used in. | 
|  | 5943 | BasicBlock *UserBB = User->getParent(); | 
|  | 5944 | if (UserBB == DefBB) continue; | 
|  | 5945 |  | 
|  | 5946 | // Both src and def are live in this block. Rewrite the use. | 
|  | 5947 | Instruction *&InsertedTrunc = InsertedTruncs[UserBB]; | 
|  | 5948 |  | 
|  | 5949 | if (!InsertedTrunc) { | 
| Bill Wendling | 8ddfc09 | 2011-08-16 20:45:24 +0000 | [diff] [blame] | 5950 | BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt(); | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 5951 | assert(InsertPt != UserBB->end()); | 
|  | 5952 | InsertedTrunc = new TruncInst(I, Src->getType(), "", &*InsertPt); | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 5953 | InsertedInsts.insert(InsertedTrunc); | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5954 | } | 
|  | 5955 |  | 
|  | 5956 | // Replace a use of the {s|z}ext source with a use of the result. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 5957 | U = InsertedTrunc; | 
| Cameron Zwarich | ced753f | 2011-01-05 17:27:27 +0000 | [diff] [blame] | 5958 | ++NumExtUses; | 
| Evan Cheng | d3d8017 | 2007-12-05 23:58:20 +0000 | [diff] [blame] | 5959 | MadeChange = true; | 
|  | 5960 | } | 
|  | 5961 |  | 
|  | 5962 | return MadeChange; | 
|  | 5963 | } | 
|  | 5964 |  | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 5965 | // Find loads whose uses only use some of the loaded value's bits.  Add an "and" | 
|  | 5966 | // just after the load if the target can fold this into one extload instruction, | 
|  | 5967 | // with the hope of eliminating some of the other later "and" instructions using | 
|  | 5968 | // the loaded value.  "and"s that are made trivially redundant by the insertion | 
|  | 5969 | // of the new "and" are removed by this function, while others (e.g. those whose | 
|  | 5970 | // path from the load goes through a phi) are left for isel to potentially | 
|  | 5971 | // remove. | 
|  | 5972 | // | 
|  | 5973 | // For example: | 
|  | 5974 | // | 
|  | 5975 | // b0: | 
|  | 5976 | //   x = load i32 | 
|  | 5977 | //   ... | 
|  | 5978 | // b1: | 
|  | 5979 | //   y = and x, 0xff | 
|  | 5980 | //   z = use y | 
|  | 5981 | // | 
|  | 5982 | // becomes: | 
|  | 5983 | // | 
|  | 5984 | // b0: | 
|  | 5985 | //   x = load i32 | 
|  | 5986 | //   x' = and x, 0xff | 
|  | 5987 | //   ... | 
|  | 5988 | // b1: | 
|  | 5989 | //   z = use x' | 
|  | 5990 | // | 
|  | 5991 | // whereas: | 
|  | 5992 | // | 
|  | 5993 | // b0: | 
|  | 5994 | //   x1 = load i32 | 
|  | 5995 | //   ... | 
|  | 5996 | // b1: | 
|  | 5997 | //   x2 = load i32 | 
|  | 5998 | //   ... | 
|  | 5999 | // b2: | 
|  | 6000 | //   x = phi x1, x2 | 
|  | 6001 | //   y = and x, 0xff | 
|  | 6002 | // | 
|  | 6003 | // becomes (after a call to optimizeLoadExt for each load): | 
|  | 6004 | // | 
|  | 6005 | // b0: | 
|  | 6006 | //   x1 = load i32 | 
|  | 6007 | //   x1' = and x1, 0xff | 
|  | 6008 | //   ... | 
|  | 6009 | // b1: | 
|  | 6010 | //   x2 = load i32 | 
|  | 6011 | //   x2' = and x2, 0xff | 
|  | 6012 | //   ... | 
|  | 6013 | // b2: | 
|  | 6014 | //   x = phi x1', x2' | 
|  | 6015 | //   y = and x, 0xff | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6016 | bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) { | 
| Vedant Kumar | b3091da | 2018-07-06 20:17:42 +0000 | [diff] [blame] | 6017 | if (!Load->isSimple() || !Load->getType()->isIntOrPtrTy()) | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6018 | return false; | 
|  | 6019 |  | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 6020 | // Skip loads we've already transformed. | 
|  | 6021 | if (Load->hasOneUse() && | 
|  | 6022 | InsertedInsts.count(cast<Instruction>(*Load->user_begin()))) | 
|  | 6023 | return false; | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6024 |  | 
|  | 6025 | // Look at all uses of Load, looking through phis, to determine how many bits | 
|  | 6026 | // of the loaded value are needed. | 
|  | 6027 | SmallVector<Instruction *, 8> WorkList; | 
|  | 6028 | SmallPtrSet<Instruction *, 16> Visited; | 
|  | 6029 | SmallVector<Instruction *, 8> AndsToMaybeRemove; | 
|  | 6030 | for (auto *U : Load->users()) | 
|  | 6031 | WorkList.push_back(cast<Instruction>(U)); | 
|  | 6032 |  | 
|  | 6033 | EVT LoadResultVT = TLI->getValueType(*DL, Load->getType()); | 
|  | 6034 | unsigned BitWidth = LoadResultVT.getSizeInBits(); | 
|  | 6035 | APInt DemandBits(BitWidth, 0); | 
|  | 6036 | APInt WidestAndBits(BitWidth, 0); | 
|  | 6037 |  | 
|  | 6038 | while (!WorkList.empty()) { | 
|  | 6039 | Instruction *I = WorkList.back(); | 
|  | 6040 | WorkList.pop_back(); | 
|  | 6041 |  | 
|  | 6042 | // Break use-def graph loops. | 
|  | 6043 | if (!Visited.insert(I).second) | 
|  | 6044 | continue; | 
|  | 6045 |  | 
|  | 6046 | // For a PHI node, push all of its users. | 
|  | 6047 | if (auto *Phi = dyn_cast<PHINode>(I)) { | 
|  | 6048 | for (auto *U : Phi->users()) | 
|  | 6049 | WorkList.push_back(cast<Instruction>(U)); | 
|  | 6050 | continue; | 
|  | 6051 | } | 
|  | 6052 |  | 
|  | 6053 | switch (I->getOpcode()) { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6054 | case Instruction::And: { | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6055 | auto *AndC = dyn_cast<ConstantInt>(I->getOperand(1)); | 
|  | 6056 | if (!AndC) | 
|  | 6057 | return false; | 
|  | 6058 | APInt AndBits = AndC->getValue(); | 
|  | 6059 | DemandBits |= AndBits; | 
|  | 6060 | // Keep track of the widest and mask we see. | 
|  | 6061 | if (AndBits.ugt(WidestAndBits)) | 
|  | 6062 | WidestAndBits = AndBits; | 
|  | 6063 | if (AndBits == WidestAndBits && I->getOperand(0) == Load) | 
|  | 6064 | AndsToMaybeRemove.push_back(I); | 
|  | 6065 | break; | 
|  | 6066 | } | 
|  | 6067 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6068 | case Instruction::Shl: { | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6069 | auto *ShlC = dyn_cast<ConstantInt>(I->getOperand(1)); | 
|  | 6070 | if (!ShlC) | 
|  | 6071 | return false; | 
|  | 6072 | uint64_t ShiftAmt = ShlC->getLimitedValue(BitWidth - 1); | 
| Craig Topper | fc947bc | 2017-04-18 17:14:21 +0000 | [diff] [blame] | 6073 | DemandBits.setLowBits(BitWidth - ShiftAmt); | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6074 | break; | 
|  | 6075 | } | 
|  | 6076 |  | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6077 | case Instruction::Trunc: { | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6078 | EVT TruncVT = TLI->getValueType(*DL, I->getType()); | 
|  | 6079 | unsigned TruncBitWidth = TruncVT.getSizeInBits(); | 
| Craig Topper | fc947bc | 2017-04-18 17:14:21 +0000 | [diff] [blame] | 6080 | DemandBits.setLowBits(TruncBitWidth); | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6081 | break; | 
|  | 6082 | } | 
|  | 6083 |  | 
|  | 6084 | default: | 
|  | 6085 | return false; | 
|  | 6086 | } | 
|  | 6087 | } | 
|  | 6088 |  | 
|  | 6089 | uint32_t ActiveBits = DemandBits.getActiveBits(); | 
|  | 6090 | // Avoid hoisting (and (load x) 1) since it is unlikely to be folded by the | 
|  | 6091 | // target even if isLoadExtLegal says an i1 EXTLOAD is valid.  For example, | 
|  | 6092 | // for the AArch64 target isLoadExtLegal(ZEXTLOAD, i32, i1) returns true, but | 
|  | 6093 | // (and (load x) 1) is not matched as a single instruction, rather as a LDR | 
|  | 6094 | // followed by an AND. | 
|  | 6095 | // TODO: Look into removing this restriction by fixing backends to either | 
|  | 6096 | // return false for isLoadExtLegal for i1 or have them select this pattern to | 
|  | 6097 | // a single instruction. | 
|  | 6098 | // | 
|  | 6099 | // Also avoid hoisting if we didn't see any ands with the exact DemandBits | 
|  | 6100 | // mask, since these are the only ands that will be removed by isel. | 
| Craig Topper | d33ee1b | 2017-04-03 16:34:59 +0000 | [diff] [blame] | 6101 | if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) || | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6102 | WidestAndBits != DemandBits) | 
|  | 6103 | return false; | 
|  | 6104 |  | 
|  | 6105 | LLVMContext &Ctx = Load->getType()->getContext(); | 
|  | 6106 | Type *TruncTy = Type::getIntNTy(Ctx, ActiveBits); | 
|  | 6107 | EVT TruncVT = TLI->getValueType(*DL, TruncTy); | 
|  | 6108 |  | 
|  | 6109 | // Reject cases that won't be matched as extloads. | 
|  | 6110 | if (!LoadResultVT.bitsGT(TruncVT) || !TruncVT.isRound() || | 
|  | 6111 | !TLI->isLoadExtLegal(ISD::ZEXTLOAD, LoadResultVT, TruncVT)) | 
|  | 6112 | return false; | 
|  | 6113 |  | 
|  | 6114 | IRBuilder<> Builder(Load->getNextNode()); | 
| Simon Pilgrim | e746380 | 2019-10-08 17:00:01 +0000 | [diff] [blame] | 6115 | auto *NewAnd = cast<Instruction>( | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6116 | Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits))); | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 6117 | // Mark this instruction as "inserted by CGP", so that other | 
|  | 6118 | // optimizations don't touch it. | 
|  | 6119 | InsertedInsts.insert(NewAnd); | 
| Geoff Berry | 5256fca | 2015-11-20 22:34:39 +0000 | [diff] [blame] | 6120 |  | 
|  | 6121 | // Replace all uses of load with new and (except for the use of load in the | 
|  | 6122 | // new and itself). | 
|  | 6123 | Load->replaceAllUsesWith(NewAnd); | 
|  | 6124 | NewAnd->setOperand(0, Load); | 
|  | 6125 |  | 
|  | 6126 | // Remove any and instructions that are now redundant. | 
|  | 6127 | for (auto *And : AndsToMaybeRemove) | 
|  | 6128 | // Check that the and mask is the same as the one we decided to put on the | 
|  | 6129 | // new and. | 
|  | 6130 | if (cast<ConstantInt>(And->getOperand(1))->getValue() == DemandBits) { | 
|  | 6131 | And->replaceAllUsesWith(NewAnd); | 
|  | 6132 | if (&*CurInstIterator == And) | 
|  | 6133 | CurInstIterator = std::next(And->getIterator()); | 
|  | 6134 | And->eraseFromParent(); | 
|  | 6135 | ++NumAndUses; | 
|  | 6136 | } | 
|  | 6137 |  | 
|  | 6138 | ++NumAndsAdded; | 
|  | 6139 | return true; | 
|  | 6140 | } | 
|  | 6141 |  | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6142 | /// Check if V (an operand of a select instruction) is an expensive instruction | 
|  | 6143 | /// that is only used once. | 
|  | 6144 | static bool sinkSelectOperand(const TargetTransformInfo *TTI, Value *V) { | 
|  | 6145 | auto *I = dyn_cast<Instruction>(V); | 
|  | 6146 | // If it's safe to speculatively execute, then it should not have side | 
|  | 6147 | // effects; therefore, it's safe to sink and possibly *not* execute. | 
| Rafael Espindola | 84921b9 | 2015-10-24 23:11:13 +0000 | [diff] [blame] | 6148 | return I && I->hasOneUse() && isSafeToSpeculativelyExecute(I) && | 
| Sam Parker | e9c9329 | 2020-04-27 09:02:14 +0100 | [diff] [blame] | 6149 | TTI->getUserCost(I, TargetTransformInfo::TCK_SizeAndLatency) >= | 
|  | 6150 | TargetTransformInfo::TCC_Expensive; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6151 | } | 
|  | 6152 |  | 
| Sanjay Patel | 4ac6b11 | 2015-09-21 22:47:23 +0000 | [diff] [blame] | 6153 | /// Returns true if a SelectInst should be turned into an explicit branch. | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6154 | static bool isFormingBranchFromSelectProfitable(const TargetTransformInfo *TTI, | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 6155 | const TargetLowering *TLI, | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6156 | SelectInst *SI) { | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 6157 | // If even a predictable select is cheap, then a branch can't be cheaper. | 
|  | 6158 | if (!TLI->isPredictableSelectExpensive()) | 
|  | 6159 | return false; | 
|  | 6160 |  | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6161 | // FIXME: This should use the same heuristics as IfConversion to determine | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 6162 | // whether a select is better represented as a branch. | 
|  | 6163 |  | 
|  | 6164 | // If metadata tells us that the select condition is obviously predictable, | 
|  | 6165 | // then we want to replace the select with a branch. | 
|  | 6166 | uint64_t TrueWeight, FalseWeight; | 
|  | 6167 | if (SI->extractProfMetadata(TrueWeight, FalseWeight)) { | 
|  | 6168 | uint64_t Max = std::max(TrueWeight, FalseWeight); | 
|  | 6169 | uint64_t Sum = TrueWeight + FalseWeight; | 
| Sanjay Patel | c7b91e6 | 2016-05-09 17:31:55 +0000 | [diff] [blame] | 6170 | if (Sum != 0) { | 
|  | 6171 | auto Probability = BranchProbability::getBranchProbability(Max, Sum); | 
|  | 6172 | if (Probability > TLI->getPredictableBranchThreshold()) | 
|  | 6173 | return true; | 
|  | 6174 | } | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 6175 | } | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6176 |  | 
|  | 6177 | CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition()); | 
|  | 6178 |  | 
| Sanjay Patel | 4e65276 | 2015-09-28 22:14:51 +0000 | [diff] [blame] | 6179 | // If a branch is predictable, an out-of-order CPU can avoid blocking on its | 
|  | 6180 | // comparison condition. If the compare has more than one use, there's | 
|  | 6181 | // probably another cmov or setcc around, so it's not worth emitting a branch. | 
| Sanjay Patel | 5e5f0e9 | 2015-09-28 21:44:46 +0000 | [diff] [blame] | 6182 | if (!Cmp || !Cmp->hasOneUse()) | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6183 | return false; | 
|  | 6184 |  | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6185 | // If either operand of the select is expensive and only needed on one side | 
|  | 6186 | // of the select, we should form a branch. | 
|  | 6187 | if (sinkSelectOperand(TTI, SI->getTrueValue()) || | 
|  | 6188 | sinkSelectOperand(TTI, SI->getFalseValue())) | 
|  | 6189 | return true; | 
|  | 6190 |  | 
|  | 6191 | return false; | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6192 | } | 
|  | 6193 |  | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6194 | /// If \p isTrue is true, return the true value of \p SI, otherwise return | 
|  | 6195 | /// false value of \p SI. If the true/false value of \p SI is defined by any | 
|  | 6196 | /// select instructions in \p Selects, look through the defining select | 
|  | 6197 | /// instruction until the true/false value is not defined in \p Selects. | 
|  | 6198 | static Value *getTrueOrFalseValue( | 
|  | 6199 | SelectInst *SI, bool isTrue, | 
|  | 6200 | const SmallPtrSet<const Instruction *, 2> &Selects) { | 
| Simon Pilgrim | 38ef296 | 2019-05-09 10:51:26 +0000 | [diff] [blame] | 6201 | Value *V = nullptr; | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6202 |  | 
|  | 6203 | for (SelectInst *DefSI = SI; DefSI != nullptr && Selects.count(DefSI); | 
|  | 6204 | DefSI = dyn_cast<SelectInst>(V)) { | 
| Dehao Chen | c32d712 | 2016-09-12 20:29:54 +0000 | [diff] [blame] | 6205 | assert(DefSI->getCondition() == SI->getCondition() && | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6206 | "The condition of DefSI does not match with SI"); | 
|  | 6207 | V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue()); | 
|  | 6208 | } | 
| Simon Pilgrim | 38ef296 | 2019-05-09 10:51:26 +0000 | [diff] [blame] | 6209 |  | 
|  | 6210 | assert(V && "Failed to get select true/false value"); | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6211 | return V; | 
|  | 6212 | } | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6213 |  | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 6214 | bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) { | 
|  | 6215 | assert(Shift->isShift() && "Expected a shift"); | 
|  | 6216 |  | 
|  | 6217 | // If this is (1) a vector shift, (2) shifts by scalars are cheaper than | 
|  | 6218 | // general vector shifts, and (3) the shift amount is a select-of-splatted | 
|  | 6219 | // values, hoist the shifts before the select: | 
|  | 6220 | //   shift Op0, (select Cond, TVal, FVal) --> | 
|  | 6221 | //   select Cond, (shift Op0, TVal), (shift Op0, FVal) | 
|  | 6222 | // | 
|  | 6223 | // This is inverting a generic IR transform when we know that the cost of a | 
|  | 6224 | // general vector shift is more than the cost of 2 shift-by-scalars. | 
|  | 6225 | // We can't do this effectively in SDAG because we may not be able to | 
|  | 6226 | // determine if the select operands are splats from within a basic block. | 
|  | 6227 | Type *Ty = Shift->getType(); | 
|  | 6228 | if (!Ty->isVectorTy() || !TLI->isVectorShiftByScalarCheap(Ty)) | 
|  | 6229 | return false; | 
|  | 6230 | Value *Cond, *TVal, *FVal; | 
|  | 6231 | if (!match(Shift->getOperand(1), | 
|  | 6232 | m_OneUse(m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal))))) | 
|  | 6233 | return false; | 
|  | 6234 | if (!isSplatValue(TVal) || !isSplatValue(FVal)) | 
|  | 6235 | return false; | 
|  | 6236 |  | 
|  | 6237 | IRBuilder<> Builder(Shift); | 
|  | 6238 | BinaryOperator::BinaryOps Opcode = Shift->getOpcode(); | 
|  | 6239 | Value *NewTVal = Builder.CreateBinOp(Opcode, Shift->getOperand(0), TVal); | 
|  | 6240 | Value *NewFVal = Builder.CreateBinOp(Opcode, Shift->getOperand(0), FVal); | 
|  | 6241 | Value *NewSel = Builder.CreateSelect(Cond, NewTVal, NewFVal); | 
|  | 6242 | Shift->replaceAllUsesWith(NewSel); | 
|  | 6243 | Shift->eraseFromParent(); | 
|  | 6244 | return true; | 
|  | 6245 | } | 
|  | 6246 |  | 
| Sanjay Patel | 5be37cb | 2020-05-15 15:22:30 -0400 | [diff] [blame] | 6247 | bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) { | 
|  | 6248 | Intrinsic::ID Opcode = Fsh->getIntrinsicID(); | 
|  | 6249 | assert((Opcode == Intrinsic::fshl || Opcode == Intrinsic::fshr) && | 
|  | 6250 | "Expected a funnel shift"); | 
|  | 6251 |  | 
|  | 6252 | // If this is (1) a vector funnel shift, (2) shifts by scalars are cheaper | 
|  | 6253 | // than general vector shifts, and (3) the shift amount is select-of-splatted | 
|  | 6254 | // values, hoist the funnel shifts before the select: | 
|  | 6255 | //   fsh Op0, Op1, (select Cond, TVal, FVal) --> | 
|  | 6256 | //   select Cond, (fsh Op0, Op1, TVal), (fsh Op0, Op1, FVal) | 
|  | 6257 | // | 
|  | 6258 | // This is inverting a generic IR transform when we know that the cost of a | 
|  | 6259 | // general vector shift is more than the cost of 2 shift-by-scalars. | 
|  | 6260 | // We can't do this effectively in SDAG because we may not be able to | 
|  | 6261 | // determine if the select operands are splats from within a basic block. | 
|  | 6262 | Type *Ty = Fsh->getType(); | 
|  | 6263 | if (!Ty->isVectorTy() || !TLI->isVectorShiftByScalarCheap(Ty)) | 
|  | 6264 | return false; | 
|  | 6265 | Value *Cond, *TVal, *FVal; | 
|  | 6266 | if (!match(Fsh->getOperand(2), | 
|  | 6267 | m_OneUse(m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal))))) | 
|  | 6268 | return false; | 
|  | 6269 | if (!isSplatValue(TVal) || !isSplatValue(FVal)) | 
|  | 6270 | return false; | 
|  | 6271 |  | 
|  | 6272 | IRBuilder<> Builder(Fsh); | 
|  | 6273 | Value *X = Fsh->getOperand(0), *Y = Fsh->getOperand(1); | 
|  | 6274 | Value *NewTVal = Builder.CreateIntrinsic(Opcode, Ty, { X, Y, TVal }); | 
|  | 6275 | Value *NewFVal = Builder.CreateIntrinsic(Opcode, Ty, { X, Y, FVal }); | 
|  | 6276 | Value *NewSel = Builder.CreateSelect(Cond, NewTVal, NewFVal); | 
|  | 6277 | Fsh->replaceAllUsesWith(NewSel); | 
|  | 6278 | Fsh->eraseFromParent(); | 
|  | 6279 | return true; | 
|  | 6280 | } | 
|  | 6281 |  | 
| Nadav Rotem | 9d83202 | 2012-09-02 12:10:19 +0000 | [diff] [blame] | 6282 | /// If we have a SelectInst that will likely profit from branch prediction, | 
|  | 6283 | /// turn it into a branch. | 
| Teresa Johnson | b7e2138 | 2019-03-27 18:44:25 +0000 | [diff] [blame] | 6284 | bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { | 
| Vedant Kumar | fbc3873 | 2018-08-21 23:42:23 +0000 | [diff] [blame] | 6285 | // If branch conversion isn't desirable, exit early. | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 6286 | if (DisableSelectToBranch || OptSize || | 
|  | 6287 | llvm::shouldOptimizeForSize(SI->getParent(), PSI, BFI.get())) | 
| Vedant Kumar | fbc3873 | 2018-08-21 23:42:23 +0000 | [diff] [blame] | 6288 | return false; | 
| Sanjay Patel | 2cec4b5 | 2019-09-25 13:29:09 +0000 | [diff] [blame] | 6289 |  | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6290 | // Find all consecutive select instructions that share the same condition. | 
|  | 6291 | SmallVector<SelectInst *, 2> ASI; | 
|  | 6292 | ASI.push_back(SI); | 
| David Blaikie | 7d30653 | 2018-08-28 00:55:19 +0000 | [diff] [blame] | 6293 | for (BasicBlock::iterator It = ++BasicBlock::iterator(SI); | 
|  | 6294 | It != SI->getParent()->end(); ++It) { | 
|  | 6295 | SelectInst *I = dyn_cast<SelectInst>(&*It); | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6296 | if (I && SI->getCondition() == I->getCondition()) { | 
|  | 6297 | ASI.push_back(I); | 
|  | 6298 | } else { | 
|  | 6299 | break; | 
|  | 6300 | } | 
|  | 6301 | } | 
|  | 6302 |  | 
|  | 6303 | SelectInst *LastSI = ASI.back(); | 
|  | 6304 | // Increment the current iterator to skip all the rest of select instructions | 
|  | 6305 | // because they will be either "not lowered" or "all lowered" to branch. | 
|  | 6306 | CurInstIterator = std::next(LastSI->getIterator()); | 
|  | 6307 |  | 
| Nadav Rotem | 9d83202 | 2012-09-02 12:10:19 +0000 | [diff] [blame] | 6308 | bool VectorCond = !SI->getCondition()->getType()->isIntegerTy(1); | 
|  | 6309 |  | 
|  | 6310 | // Can we convert the 'select' to CF ? | 
| Vedant Kumar | fbc3873 | 2018-08-21 23:42:23 +0000 | [diff] [blame] | 6311 | if (VectorCond || SI->getMetadata(LLVMContext::MD_unpredictable)) | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6312 | return false; | 
|  | 6313 |  | 
| Nadav Rotem | 9d83202 | 2012-09-02 12:10:19 +0000 | [diff] [blame] | 6314 | TargetLowering::SelectSupportKind SelectKind; | 
|  | 6315 | if (VectorCond) | 
|  | 6316 | SelectKind = TargetLowering::VectorMaskSelect; | 
|  | 6317 | else if (SI->getType()->isVectorTy()) | 
|  | 6318 | SelectKind = TargetLowering::ScalarCondVectorVal; | 
|  | 6319 | else | 
|  | 6320 | SelectKind = TargetLowering::ScalarValSelect; | 
|  | 6321 |  | 
| Sanjay Patel | d66607b | 2016-04-26 17:11:17 +0000 | [diff] [blame] | 6322 | if (TLI->isSelectSupported(SelectKind) && | 
|  | 6323 | !isFormingBranchFromSelectProfitable(TTI, TLI, SI)) | 
|  | 6324 | return false; | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6325 |  | 
| Teresa Johnson | b7e2138 | 2019-03-27 18:44:25 +0000 | [diff] [blame] | 6326 | // The DominatorTree needs to be rebuilt by any consumers after this | 
|  | 6327 | // transformation. We simply reset here rather than setting the ModifiedDT | 
|  | 6328 | // flag to avoid restarting the function walk in runOnFunction for each | 
|  | 6329 | // select optimized. | 
|  | 6330 | DT.reset(); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6331 |  | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6332 | // Transform a sequence like this: | 
|  | 6333 | //    start: | 
|  | 6334 | //       %cmp = cmp uge i32 %a, %b | 
|  | 6335 | //       %sel = select i1 %cmp, i32 %c, i32 %d | 
|  | 6336 | // | 
|  | 6337 | // Into: | 
|  | 6338 | //    start: | 
|  | 6339 | //       %cmp = cmp uge i32 %a, %b | 
| Juneyoung Lee | 6ad6360 | 2020-03-15 01:34:33 +0900 | [diff] [blame] | 6340 | //       %cmp.frozen = freeze %cmp | 
|  | 6341 | //       br i1 %cmp.frozen, label %select.true, label %select.false | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6342 | //    select.true: | 
|  | 6343 | //       br label %select.end | 
|  | 6344 | //    select.false: | 
|  | 6345 | //       br label %select.end | 
|  | 6346 | //    select.end: | 
|  | 6347 | //       %sel = phi i32 [ %c, %select.true ], [ %d, %select.false ] | 
|  | 6348 | // | 
| Juneyoung Lee | 07a4154 | 2020-03-17 01:10:02 +0900 | [diff] [blame] | 6349 | // %cmp should be frozen, otherwise it may introduce undefined behavior. | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6350 | // In addition, we may sink instructions that produce %c or %d from | 
|  | 6351 | // the entry block into the destination(s) of the new branch. | 
|  | 6352 | // If the true or false blocks do not contain a sunken instruction, that | 
|  | 6353 | // block and its branch may be optimized away. In that case, one side of the | 
|  | 6354 | // first branch will point directly to select.end, and the corresponding PHI | 
|  | 6355 | // predecessor block will be the start block. | 
|  | 6356 |  | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6357 | // First, we split the block containing the select into 2 blocks. | 
|  | 6358 | BasicBlock *StartBlock = SI->getParent(); | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6359 | BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(LastSI)); | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6360 | BasicBlock *EndBlock = StartBlock->splitBasicBlock(SplitPt, "select.end"); | 
| Hiroshi Yamauchi | ddbc728 | 2020-01-21 15:49:04 -0800 | [diff] [blame] | 6361 | BFI->setBlockFreq(EndBlock, BFI->getBlockFreq(StartBlock).getFrequency()); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6362 |  | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6363 | // Delete the unconditional branch that was just created by the split. | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6364 | StartBlock->getTerminator()->eraseFromParent(); | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6365 |  | 
|  | 6366 | // These are the new basic blocks for the conditional branch. | 
|  | 6367 | // At least one will become an actual new basic block. | 
|  | 6368 | BasicBlock *TrueBlock = nullptr; | 
|  | 6369 | BasicBlock *FalseBlock = nullptr; | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6370 | BranchInst *TrueBranch = nullptr; | 
|  | 6371 | BranchInst *FalseBranch = nullptr; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6372 |  | 
|  | 6373 | // Sink expensive instructions into the conditional blocks to avoid executing | 
|  | 6374 | // them speculatively. | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6375 | for (SelectInst *SI : ASI) { | 
|  | 6376 | if (sinkSelectOperand(TTI, SI->getTrueValue())) { | 
|  | 6377 | if (TrueBlock == nullptr) { | 
|  | 6378 | TrueBlock = BasicBlock::Create(SI->getContext(), "select.true.sink", | 
|  | 6379 | EndBlock->getParent(), EndBlock); | 
|  | 6380 | TrueBranch = BranchInst::Create(EndBlock, TrueBlock); | 
| Vedant Kumar | 1e8a2c9 | 2018-08-22 00:10:37 +0000 | [diff] [blame] | 6381 | TrueBranch->setDebugLoc(SI->getDebugLoc()); | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6382 | } | 
|  | 6383 | auto *TrueInst = cast<Instruction>(SI->getTrueValue()); | 
|  | 6384 | TrueInst->moveBefore(TrueBranch); | 
|  | 6385 | } | 
|  | 6386 | if (sinkSelectOperand(TTI, SI->getFalseValue())) { | 
|  | 6387 | if (FalseBlock == nullptr) { | 
|  | 6388 | FalseBlock = BasicBlock::Create(SI->getContext(), "select.false.sink", | 
|  | 6389 | EndBlock->getParent(), EndBlock); | 
|  | 6390 | FalseBranch = BranchInst::Create(EndBlock, FalseBlock); | 
| Vedant Kumar | 1e8a2c9 | 2018-08-22 00:10:37 +0000 | [diff] [blame] | 6391 | FalseBranch->setDebugLoc(SI->getDebugLoc()); | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6392 | } | 
|  | 6393 | auto *FalseInst = cast<Instruction>(SI->getFalseValue()); | 
|  | 6394 | FalseInst->moveBefore(FalseBranch); | 
|  | 6395 | } | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6396 | } | 
|  | 6397 |  | 
|  | 6398 | // If there was nothing to sink, then arbitrarily choose the 'false' side | 
|  | 6399 | // for a new input value to the PHI. | 
|  | 6400 | if (TrueBlock == FalseBlock) { | 
|  | 6401 | assert(TrueBlock == nullptr && | 
|  | 6402 | "Unexpected basic block transform while optimizing select"); | 
|  | 6403 |  | 
|  | 6404 | FalseBlock = BasicBlock::Create(SI->getContext(), "select.false", | 
|  | 6405 | EndBlock->getParent(), EndBlock); | 
| Vedant Kumar | 1e8a2c9 | 2018-08-22 00:10:37 +0000 | [diff] [blame] | 6406 | auto *FalseBranch = BranchInst::Create(EndBlock, FalseBlock); | 
|  | 6407 | FalseBranch->setDebugLoc(SI->getDebugLoc()); | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6408 | } | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6409 |  | 
|  | 6410 | // Insert the real conditional branch based on the original condition. | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6411 | // If we did not create a new block for one of the 'true' or 'false' paths | 
|  | 6412 | // of the condition, it means that side of the branch goes to the end block | 
|  | 6413 | // directly and the path originates from the start block from the point of | 
|  | 6414 | // view of the new PHI. | 
| Xinliang David Li | 241e6c7 | 2016-09-03 21:26:36 +0000 | [diff] [blame] | 6415 | BasicBlock *TT, *FT; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6416 | if (TrueBlock == nullptr) { | 
| Xinliang David Li | 241e6c7 | 2016-09-03 21:26:36 +0000 | [diff] [blame] | 6417 | TT = EndBlock; | 
|  | 6418 | FT = FalseBlock; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6419 | TrueBlock = StartBlock; | 
|  | 6420 | } else if (FalseBlock == nullptr) { | 
| Xinliang David Li | 241e6c7 | 2016-09-03 21:26:36 +0000 | [diff] [blame] | 6421 | TT = TrueBlock; | 
|  | 6422 | FT = EndBlock; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6423 | FalseBlock = StartBlock; | 
|  | 6424 | } else { | 
| Xinliang David Li | 241e6c7 | 2016-09-03 21:26:36 +0000 | [diff] [blame] | 6425 | TT = TrueBlock; | 
|  | 6426 | FT = FalseBlock; | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6427 | } | 
| Juneyoung Lee | 6ad6360 | 2020-03-15 01:34:33 +0900 | [diff] [blame] | 6428 | IRBuilder<> IB(SI); | 
|  | 6429 | auto CondFr = IB.CreateFreeze(SI->getCondition(), SI->getName() + ".frozen"); | 
|  | 6430 | IB.CreateCondBr(CondFr, TT, FT, SI); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6431 |  | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6432 | SmallPtrSet<const Instruction *, 2> INS; | 
|  | 6433 | INS.insert(ASI.begin(), ASI.end()); | 
|  | 6434 | // Use reverse iterator because later select may use the value of the | 
|  | 6435 | // earlier select, and we need to propagate value through earlier select | 
|  | 6436 | // to get the PHI operand. | 
|  | 6437 | for (auto It = ASI.rbegin(); It != ASI.rend(); ++It) { | 
|  | 6438 | SelectInst *SI = *It; | 
|  | 6439 | // The select itself is replaced with a PHI Node. | 
|  | 6440 | PHINode *PN = PHINode::Create(SI->getType(), 2, "", &EndBlock->front()); | 
|  | 6441 | PN->takeName(SI); | 
|  | 6442 | PN->addIncoming(getTrueOrFalseValue(SI, true, INS), TrueBlock); | 
|  | 6443 | PN->addIncoming(getTrueOrFalseValue(SI, false, INS), FalseBlock); | 
| Vedant Kumar | 1e8a2c9 | 2018-08-22 00:10:37 +0000 | [diff] [blame] | 6444 | PN->setDebugLoc(SI->getDebugLoc()); | 
| Sanjay Patel | 69a50a1 | 2015-10-19 21:59:12 +0000 | [diff] [blame] | 6445 |  | 
| Dehao Chen | 9bbb941 | 2016-09-12 20:23:28 +0000 | [diff] [blame] | 6446 | SI->replaceAllUsesWith(PN); | 
|  | 6447 | SI->eraseFromParent(); | 
|  | 6448 | INS.erase(SI); | 
|  | 6449 | ++NumSelectsExpanded; | 
|  | 6450 | } | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6451 |  | 
|  | 6452 | // Instruct OptimizeBlock to skip to the next block. | 
|  | 6453 | CurInstIterator = StartBlock->end(); | 
| Benjamin Kramer | 047d7ca | 2012-05-05 12:49:22 +0000 | [diff] [blame] | 6454 | return true; | 
|  | 6455 | } | 
|  | 6456 |  | 
| David Green | fa15255 | 2020-05-13 14:35:32 +0100 | [diff] [blame] | 6457 | /// Some targets only accept certain types for splat inputs. For example a VDUP | 
|  | 6458 | /// in MVE takes a GPR (integer) register, and the instruction that incorporate | 
|  | 6459 | /// a VDUP (such as a VADD qd, qm, rm) also require a gpr register. | 
| Sanjay Patel | 26e742f | 2020-05-14 08:33:59 -0400 | [diff] [blame] | 6460 | bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) { | 
| David Green | fa15255 | 2020-05-13 14:35:32 +0100 | [diff] [blame] | 6461 | if (!match(SVI, | 
|  | 6462 | m_ShuffleVector(m_InsertElement(m_Undef(), m_Value(), m_ZeroInt()), | 
|  | 6463 | m_Undef(), m_ZeroMask()))) | 
|  | 6464 | return false; | 
|  | 6465 | Type *NewType = TLI->shouldConvertSplatType(SVI); | 
|  | 6466 | if (!NewType) | 
|  | 6467 | return false; | 
|  | 6468 |  | 
|  | 6469 | VectorType *SVIVecType = cast<VectorType>(SVI->getType()); | 
| David Green | fa15255 | 2020-05-13 14:35:32 +0100 | [diff] [blame] | 6470 | assert(!NewType->isVectorTy() && "Expected a scalar type!"); | 
| Benjamin Kramer | a8bf2de | 2020-05-13 18:25:20 +0200 | [diff] [blame] | 6471 | assert(NewType->getScalarSizeInBits() == SVIVecType->getScalarSizeInBits() && | 
| David Green | fa15255 | 2020-05-13 14:35:32 +0100 | [diff] [blame] | 6472 | "Expected a type of the same size!"); | 
|  | 6473 | Type *NewVecType = VectorType::get(NewType, SVIVecType->getNumElements()); | 
|  | 6474 |  | 
|  | 6475 | // Create a bitcast (shuffle (insert (bitcast(..)))) | 
|  | 6476 | IRBuilder<> Builder(SVI->getContext()); | 
|  | 6477 | Builder.SetInsertPoint(SVI); | 
|  | 6478 | Value *BC1 = Builder.CreateBitCast( | 
|  | 6479 | cast<Instruction>(SVI->getOperand(0))->getOperand(1), NewType); | 
|  | 6480 | Value *Insert = Builder.CreateInsertElement(UndefValue::get(NewVecType), BC1, | 
|  | 6481 | (uint64_t)0); | 
|  | 6482 | Value *Shuffle = Builder.CreateShuffleVector( | 
|  | 6483 | Insert, UndefValue::get(NewVecType), SVI->getShuffleMask()); | 
|  | 6484 | Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType); | 
|  | 6485 |  | 
|  | 6486 | SVI->replaceAllUsesWith(BC2); | 
|  | 6487 | RecursivelyDeleteTriviallyDeadInstructions(SVI); | 
|  | 6488 |  | 
|  | 6489 | // Also hoist the bitcast up to its operand if it they are not in the same | 
|  | 6490 | // block. | 
|  | 6491 | if (auto *BCI = dyn_cast<Instruction>(BC1)) | 
|  | 6492 | if (auto *Op = dyn_cast<Instruction>(BCI->getOperand(0))) | 
|  | 6493 | if (BCI->getParent() != Op->getParent() && !isa<PHINode>(Op) && | 
|  | 6494 | !Op->isTerminator() && !Op->isEHPad()) | 
|  | 6495 | BCI->moveAfter(Op); | 
|  | 6496 |  | 
|  | 6497 | return true; | 
|  | 6498 | } | 
|  | 6499 |  | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6500 | bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *I) { | 
|  | 6501 | // If the operands of I can be folded into a target instruction together with | 
|  | 6502 | // I, duplicate and sink them. | 
|  | 6503 | SmallVector<Use *, 4> OpsToSink; | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 6504 | if (!TLI->shouldSinkOperands(I, OpsToSink)) | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6505 | return false; | 
|  | 6506 |  | 
|  | 6507 | // OpsToSink can contain multiple uses in a use chain (e.g. | 
|  | 6508 | // (%u1 with %u1 = shufflevector), (%u2 with %u2 = zext %u1)). The dominating | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6509 | // uses must come first, so we process the ops in reverse order so as to not | 
|  | 6510 | // create invalid IR. | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6511 | BasicBlock *TargetBB = I->getParent(); | 
|  | 6512 | bool Changed = false; | 
|  | 6513 | SmallVector<Use *, 4> ToReplace; | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6514 | for (Use *U : reverse(OpsToSink)) { | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6515 | auto *UI = cast<Instruction>(U->get()); | 
|  | 6516 | if (UI->getParent() == TargetBB || isa<PHINode>(UI)) | 
|  | 6517 | continue; | 
|  | 6518 | ToReplace.push_back(U); | 
|  | 6519 | } | 
|  | 6520 |  | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6521 | SetVector<Instruction *> MaybeDead; | 
|  | 6522 | DenseMap<Instruction *, Instruction *> NewInstructions; | 
|  | 6523 | Instruction *InsertPoint = I; | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6524 | for (Use *U : ToReplace) { | 
|  | 6525 | auto *UI = cast<Instruction>(U->get()); | 
|  | 6526 | Instruction *NI = UI->clone(); | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6527 | NewInstructions[UI] = NI; | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6528 | MaybeDead.insert(UI); | 
|  | 6529 | LLVM_DEBUG(dbgs() << "Sinking " << *UI << " to user " << *I << "\n"); | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6530 | NI->insertBefore(InsertPoint); | 
|  | 6531 | InsertPoint = NI; | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6532 | InsertedInsts.insert(NI); | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6533 |  | 
|  | 6534 | // Update the use for the new instruction, making sure that we update the | 
|  | 6535 | // sunk instruction uses, if it is part of a chain that has already been | 
|  | 6536 | // sunk. | 
|  | 6537 | Instruction *OldI = cast<Instruction>(U->getUser()); | 
|  | 6538 | if (NewInstructions.count(OldI)) | 
|  | 6539 | NewInstructions[OldI]->setOperand(U->getOperandNo(), NI); | 
|  | 6540 | else | 
|  | 6541 | U->set(NI); | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6542 | Changed = true; | 
|  | 6543 | } | 
|  | 6544 |  | 
|  | 6545 | // Remove instructions that are dead after sinking. | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6546 | for (auto *I : MaybeDead) { | 
|  | 6547 | if (!I->hasNUsesOrMore(1)) { | 
|  | 6548 | LLVM_DEBUG(dbgs() << "Removing dead instruction: " << *I << "\n"); | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6549 | I->eraseFromParent(); | 
| David Green | a6e944b | 2019-09-12 16:00:07 +0000 | [diff] [blame] | 6550 | } | 
|  | 6551 | } | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 6552 |  | 
|  | 6553 | return Changed; | 
|  | 6554 | } | 
|  | 6555 |  | 
| Sanjay Patel | 0ed9aea | 2015-11-02 23:22:49 +0000 | [diff] [blame] | 6556 | bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) { | 
| Sanjay Patel | 0ed9aea | 2015-11-02 23:22:49 +0000 | [diff] [blame] | 6557 | Value *Cond = SI->getCondition(); | 
|  | 6558 | Type *OldType = Cond->getType(); | 
|  | 6559 | LLVMContext &Context = Cond->getContext(); | 
|  | 6560 | MVT RegType = TLI->getRegisterType(Context, TLI->getValueType(*DL, OldType)); | 
|  | 6561 | unsigned RegWidth = RegType.getSizeInBits(); | 
|  | 6562 |  | 
|  | 6563 | if (RegWidth <= cast<IntegerType>(OldType)->getBitWidth()) | 
|  | 6564 | return false; | 
|  | 6565 |  | 
|  | 6566 | // If the register width is greater than the type width, expand the condition | 
|  | 6567 | // of the switch instruction and each case constant to the width of the | 
|  | 6568 | // register. By widening the type of the switch condition, subsequent | 
|  | 6569 | // comparisons (for case comparisons) will not need to be extended to the | 
|  | 6570 | // preferred register width, so we will potentially eliminate N-1 extends, | 
|  | 6571 | // where N is the number of cases in the switch. | 
|  | 6572 | auto *NewType = Type::getIntNTy(Context, RegWidth); | 
|  | 6573 |  | 
|  | 6574 | // Zero-extend the switch condition and case constants unless the switch | 
|  | 6575 | // condition is a function argument that is already being sign-extended. | 
|  | 6576 | // In that case, we can avoid an unnecessary mask/extension by sign-extending | 
|  | 6577 | // everything instead. | 
|  | 6578 | Instruction::CastOps ExtType = Instruction::ZExt; | 
|  | 6579 | if (auto *Arg = dyn_cast<Argument>(Cond)) | 
|  | 6580 | if (Arg->hasSExtAttr()) | 
|  | 6581 | ExtType = Instruction::SExt; | 
|  | 6582 |  | 
|  | 6583 | auto *ExtInst = CastInst::Create(ExtType, Cond, NewType); | 
|  | 6584 | ExtInst->insertBefore(SI); | 
| Vedant Kumar | 4760686 | 2018-08-22 01:23:31 +0000 | [diff] [blame] | 6585 | ExtInst->setDebugLoc(SI->getDebugLoc()); | 
| Sanjay Patel | 0ed9aea | 2015-11-02 23:22:49 +0000 | [diff] [blame] | 6586 | SI->setCondition(ExtInst); | 
| Chandler Carruth | 927d8e6 | 2017-04-12 07:27:28 +0000 | [diff] [blame] | 6587 | for (auto Case : SI->cases()) { | 
| Sanjay Patel | 0ed9aea | 2015-11-02 23:22:49 +0000 | [diff] [blame] | 6588 | APInt NarrowConst = Case.getCaseValue()->getValue(); | 
|  | 6589 | APInt WideConst = (ExtType == Instruction::ZExt) ? | 
|  | 6590 | NarrowConst.zext(RegWidth) : NarrowConst.sext(RegWidth); | 
|  | 6591 | Case.setValue(ConstantInt::get(Context, WideConst)); | 
|  | 6592 | } | 
|  | 6593 |  | 
|  | 6594 | return true; | 
|  | 6595 | } | 
|  | 6596 |  | 
| Zaara Syeda | 3a7578c | 2017-05-31 17:12:38 +0000 | [diff] [blame] | 6597 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6598 | namespace { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6599 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6600 | /// Helper class to promote a scalar operation to a vector one. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6601 | /// This class is used to move downward extractelement transition. | 
|  | 6602 | /// E.g., | 
|  | 6603 | /// a = vector_op <2 x i32> | 
|  | 6604 | /// b = extractelement <2 x i32> a, i32 0 | 
|  | 6605 | /// c = scalar_op b | 
|  | 6606 | /// store c | 
|  | 6607 | /// | 
|  | 6608 | /// => | 
|  | 6609 | /// a = vector_op <2 x i32> | 
|  | 6610 | /// c = vector_op a (equivalent to scalar_op on the related lane) | 
|  | 6611 | /// * d = extractelement <2 x i32> c, i32 0 | 
|  | 6612 | /// * store d | 
|  | 6613 | /// Assuming both extractelement and store can be combine, we get rid of the | 
|  | 6614 | /// transition. | 
|  | 6615 | class VectorPromoteHelper { | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 6616 | /// DataLayout associated with the current module. | 
|  | 6617 | const DataLayout &DL; | 
|  | 6618 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6619 | /// Used to perform some checks on the legality of vector operations. | 
|  | 6620 | const TargetLowering &TLI; | 
|  | 6621 |  | 
|  | 6622 | /// Used to estimated the cost of the promoted chain. | 
|  | 6623 | const TargetTransformInfo &TTI; | 
|  | 6624 |  | 
|  | 6625 | /// The transition being moved downwards. | 
|  | 6626 | Instruction *Transition; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6627 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6628 | /// The sequence of instructions to be promoted. | 
|  | 6629 | SmallVector<Instruction *, 4> InstsToBePromoted; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6630 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6631 | /// Cost of combining a store and an extract. | 
|  | 6632 | unsigned StoreExtractCombineCost; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6633 |  | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6634 | /// Instruction that will be combined with the transition. | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6635 | Instruction *CombineInst = nullptr; | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6636 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6637 | /// The instruction that represents the current end of the transition. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6638 | /// Since we are faking the promotion until we reach the end of the chain | 
|  | 6639 | /// of computation, we need a way to get the current end of the transition. | 
|  | 6640 | Instruction *getEndOfTransition() const { | 
|  | 6641 | if (InstsToBePromoted.empty()) | 
|  | 6642 | return Transition; | 
|  | 6643 | return InstsToBePromoted.back(); | 
|  | 6644 | } | 
|  | 6645 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6646 | /// Return the index of the original value in the transition. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6647 | /// E.g., for "extractelement <2 x i32> c, i32 1" the original value, | 
|  | 6648 | /// c, is at index 0. | 
|  | 6649 | unsigned getTransitionOriginalValueIdx() const { | 
|  | 6650 | assert(isa<ExtractElementInst>(Transition) && | 
|  | 6651 | "Other kind of transitions are not supported yet"); | 
|  | 6652 | return 0; | 
|  | 6653 | } | 
|  | 6654 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6655 | /// Return the index of the index in the transition. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6656 | /// E.g., for "extractelement <2 x i32> c, i32 0" the index | 
|  | 6657 | /// is at index 1. | 
|  | 6658 | unsigned getTransitionIdx() const { | 
|  | 6659 | assert(isa<ExtractElementInst>(Transition) && | 
|  | 6660 | "Other kind of transitions are not supported yet"); | 
|  | 6661 | return 1; | 
|  | 6662 | } | 
|  | 6663 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6664 | /// Get the type of the transition. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6665 | /// This is the type of the original value. | 
|  | 6666 | /// E.g., for "extractelement <2 x i32> c, i32 1" the type of the | 
|  | 6667 | /// transition is <2 x i32>. | 
|  | 6668 | Type *getTransitionType() const { | 
|  | 6669 | return Transition->getOperand(getTransitionOriginalValueIdx())->getType(); | 
|  | 6670 | } | 
|  | 6671 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6672 | /// Promote \p ToBePromoted by moving \p Def downward through. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6673 | /// I.e., we have the following sequence: | 
|  | 6674 | /// Def = Transition <ty1> a to <ty2> | 
|  | 6675 | /// b = ToBePromoted <ty2> Def, ... | 
|  | 6676 | /// => | 
|  | 6677 | /// b = ToBePromoted <ty1> a, ... | 
|  | 6678 | /// Def = Transition <ty1> ToBePromoted to <ty2> | 
|  | 6679 | void promoteImpl(Instruction *ToBePromoted); | 
|  | 6680 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6681 | /// Check whether or not it is profitable to promote all the | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6682 | /// instructions enqueued to be promoted. | 
|  | 6683 | bool isProfitableToPromote() { | 
|  | 6684 | Value *ValIdx = Transition->getOperand(getTransitionOriginalValueIdx()); | 
|  | 6685 | unsigned Index = isa<ConstantInt>(ValIdx) | 
|  | 6686 | ? cast<ConstantInt>(ValIdx)->getZExtValue() | 
|  | 6687 | : -1; | 
|  | 6688 | Type *PromotedType = getTransitionType(); | 
|  | 6689 |  | 
|  | 6690 | StoreInst *ST = cast<StoreInst>(CombineInst); | 
|  | 6691 | unsigned AS = ST->getPointerAddressSpace(); | 
|  | 6692 | unsigned Align = ST->getAlignment(); | 
|  | 6693 | // Check if this store is supported. | 
|  | 6694 | if (!TLI.allowsMisalignedMemoryAccesses( | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 6695 | TLI.getValueType(DL, ST->getValueOperand()->getType()), AS, | 
|  | 6696 | Align)) { | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6697 | // If this is not supported, there is no way we can combine | 
|  | 6698 | // the extract with the store. | 
|  | 6699 | return false; | 
|  | 6700 | } | 
|  | 6701 |  | 
|  | 6702 | // The scalar chain of computation has to pay for the transition | 
|  | 6703 | // scalar to vector. | 
|  | 6704 | // The vector chain has to account for the combining cost. | 
|  | 6705 | uint64_t ScalarCost = | 
|  | 6706 | TTI.getVectorInstrCost(Transition->getOpcode(), PromotedType, Index); | 
|  | 6707 | uint64_t VectorCost = StoreExtractCombineCost; | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 6708 | enum TargetTransformInfo::TargetCostKind CostKind = | 
|  | 6709 | TargetTransformInfo::TCK_RecipThroughput; | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6710 | for (const auto &Inst : InstsToBePromoted) { | 
|  | 6711 | // Compute the cost. | 
|  | 6712 | // By construction, all instructions being promoted are arithmetic ones. | 
|  | 6713 | // Moreover, one argument is a constant that can be viewed as a splat | 
|  | 6714 | // constant. | 
|  | 6715 | Value *Arg0 = Inst->getOperand(0); | 
|  | 6716 | bool IsArg0Constant = isa<UndefValue>(Arg0) || isa<ConstantInt>(Arg0) || | 
|  | 6717 | isa<ConstantFP>(Arg0); | 
|  | 6718 | TargetTransformInfo::OperandValueKind Arg0OVK = | 
|  | 6719 | IsArg0Constant ? TargetTransformInfo::OK_UniformConstantValue | 
|  | 6720 | : TargetTransformInfo::OK_AnyValue; | 
|  | 6721 | TargetTransformInfo::OperandValueKind Arg1OVK = | 
|  | 6722 | !IsArg0Constant ? TargetTransformInfo::OK_UniformConstantValue | 
|  | 6723 | : TargetTransformInfo::OK_AnyValue; | 
|  | 6724 | ScalarCost += TTI.getArithmeticInstrCost( | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 6725 | Inst->getOpcode(), Inst->getType(), CostKind, Arg0OVK, Arg1OVK); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6726 | VectorCost += TTI.getArithmeticInstrCost(Inst->getOpcode(), PromotedType, | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 6727 | CostKind, | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6728 | Arg0OVK, Arg1OVK); | 
|  | 6729 | } | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6730 | LLVM_DEBUG( | 
|  | 6731 | dbgs() << "Estimated cost of computation to be promoted:\nScalar: " | 
|  | 6732 | << ScalarCost << "\nVector: " << VectorCost << '\n'); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6733 | return ScalarCost > VectorCost; | 
|  | 6734 | } | 
|  | 6735 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6736 | /// Generate a constant vector with \p Val with the same | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6737 | /// number of elements as the transition. | 
|  | 6738 | /// \p UseSplat defines whether or not \p Val should be replicated | 
| Benjamin Kramer | df005cb | 2015-08-08 18:27:36 +0000 | [diff] [blame] | 6739 | /// across the whole vector. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6740 | /// In other words, if UseSplat == true, we generate <Val, Val, ..., Val>, | 
|  | 6741 | /// otherwise we generate a vector with as many undef as possible: | 
|  | 6742 | /// <undef, ..., undef, Val, undef, ..., undef> where \p Val is only | 
|  | 6743 | /// used at the index of the extract. | 
|  | 6744 | Value *getConstantVector(Constant *Val, bool UseSplat) const { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6745 | unsigned ExtractIdx = std::numeric_limits<unsigned>::max(); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6746 | if (!UseSplat) { | 
|  | 6747 | // If we cannot determine where the constant must be, we have to | 
|  | 6748 | // use a splat constant. | 
|  | 6749 | Value *ValExtractIdx = Transition->getOperand(getTransitionIdx()); | 
|  | 6750 | if (ConstantInt *CstVal = dyn_cast<ConstantInt>(ValExtractIdx)) | 
|  | 6751 | ExtractIdx = CstVal->getSExtValue(); | 
|  | 6752 | else | 
|  | 6753 | UseSplat = true; | 
|  | 6754 | } | 
|  | 6755 |  | 
| Christopher Tetreault | 889f660 | 2020-04-10 14:23:20 -0700 | [diff] [blame] | 6756 | ElementCount EC = cast<VectorType>(getTransitionType())->getElementCount(); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6757 | if (UseSplat) | 
| Huihui Zhang | 118abf2 | 2020-03-12 13:15:34 -0700 | [diff] [blame] | 6758 | return ConstantVector::getSplat(EC, Val); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6759 |  | 
| Huihui Zhang | 118abf2 | 2020-03-12 13:15:34 -0700 | [diff] [blame] | 6760 | if (!EC.Scalable) { | 
|  | 6761 | SmallVector<Constant *, 4> ConstVec; | 
|  | 6762 | UndefValue *UndefVal = UndefValue::get(Val->getType()); | 
|  | 6763 | for (unsigned Idx = 0; Idx != EC.Min; ++Idx) { | 
|  | 6764 | if (Idx == ExtractIdx) | 
|  | 6765 | ConstVec.push_back(Val); | 
|  | 6766 | else | 
|  | 6767 | ConstVec.push_back(UndefVal); | 
|  | 6768 | } | 
|  | 6769 | return ConstantVector::get(ConstVec); | 
|  | 6770 | } else | 
|  | 6771 | llvm_unreachable( | 
|  | 6772 | "Generate scalable vector for non-splat is unimplemented"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6773 | } | 
|  | 6774 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6775 | /// Check if promoting to a vector type an operand at \p OperandIdx | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6776 | /// in \p Use can trigger undefined behavior. | 
|  | 6777 | static bool canCauseUndefinedBehavior(const Instruction *Use, | 
|  | 6778 | unsigned OperandIdx) { | 
|  | 6779 | // This is not safe to introduce undef when the operand is on | 
|  | 6780 | // the right hand side of a division-like instruction. | 
|  | 6781 | if (OperandIdx != 1) | 
|  | 6782 | return false; | 
|  | 6783 | switch (Use->getOpcode()) { | 
|  | 6784 | default: | 
|  | 6785 | return false; | 
|  | 6786 | case Instruction::SDiv: | 
|  | 6787 | case Instruction::UDiv: | 
|  | 6788 | case Instruction::SRem: | 
|  | 6789 | case Instruction::URem: | 
|  | 6790 | return true; | 
|  | 6791 | case Instruction::FDiv: | 
|  | 6792 | case Instruction::FRem: | 
|  | 6793 | return !Use->hasNoNaNs(); | 
|  | 6794 | } | 
|  | 6795 | llvm_unreachable(nullptr); | 
|  | 6796 | } | 
|  | 6797 |  | 
|  | 6798 | public: | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 6799 | VectorPromoteHelper(const DataLayout &DL, const TargetLowering &TLI, | 
|  | 6800 | const TargetTransformInfo &TTI, Instruction *Transition, | 
|  | 6801 | unsigned CombineCost) | 
|  | 6802 | : DL(DL), TLI(TLI), TTI(TTI), Transition(Transition), | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6803 | StoreExtractCombineCost(CombineCost) { | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6804 | assert(Transition && "Do not know how to promote null"); | 
|  | 6805 | } | 
|  | 6806 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6807 | /// Check if we can promote \p ToBePromoted to \p Type. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6808 | bool canPromote(const Instruction *ToBePromoted) const { | 
|  | 6809 | // We could support CastInst too. | 
|  | 6810 | return isa<BinaryOperator>(ToBePromoted); | 
|  | 6811 | } | 
|  | 6812 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6813 | /// Check if it is profitable to promote \p ToBePromoted | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6814 | /// by moving downward the transition through. | 
|  | 6815 | bool shouldPromote(const Instruction *ToBePromoted) const { | 
|  | 6816 | // Promote only if all the operands can be statically expanded. | 
|  | 6817 | // Indeed, we do not want to introduce any new kind of transitions. | 
|  | 6818 | for (const Use &U : ToBePromoted->operands()) { | 
|  | 6819 | const Value *Val = U.get(); | 
|  | 6820 | if (Val == getEndOfTransition()) { | 
|  | 6821 | // If the use is a division and the transition is on the rhs, | 
|  | 6822 | // we cannot promote the operation, otherwise we may create a | 
|  | 6823 | // division by zero. | 
|  | 6824 | if (canCauseUndefinedBehavior(ToBePromoted, U.getOperandNo())) | 
|  | 6825 | return false; | 
|  | 6826 | continue; | 
|  | 6827 | } | 
|  | 6828 | if (!isa<ConstantInt>(Val) && !isa<UndefValue>(Val) && | 
|  | 6829 | !isa<ConstantFP>(Val)) | 
|  | 6830 | return false; | 
|  | 6831 | } | 
|  | 6832 | // Check that the resulting operation is legal. | 
|  | 6833 | int ISDOpcode = TLI.InstructionOpcodeToISD(ToBePromoted->getOpcode()); | 
|  | 6834 | if (!ISDOpcode) | 
|  | 6835 | return false; | 
|  | 6836 | return StressStoreExtract || | 
| Ahmed Bougacha | 026600d | 2014-11-12 23:05:03 +0000 | [diff] [blame] | 6837 | TLI.isOperationLegalOrCustom( | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 6838 | ISDOpcode, TLI.getValueType(DL, getTransitionType(), true)); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6839 | } | 
|  | 6840 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6841 | /// Check whether or not \p Use can be combined | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6842 | /// with the transition. | 
|  | 6843 | /// I.e., is it possible to do Use(Transition) => AnotherUse? | 
|  | 6844 | bool canCombine(const Instruction *Use) { return isa<StoreInst>(Use); } | 
|  | 6845 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6846 | /// Record \p ToBePromoted as part of the chain to be promoted. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6847 | void enqueueForPromotion(Instruction *ToBePromoted) { | 
|  | 6848 | InstsToBePromoted.push_back(ToBePromoted); | 
|  | 6849 | } | 
|  | 6850 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6851 | /// Set the instruction that will be combined with the transition. | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6852 | void recordCombineInstruction(Instruction *ToBeCombined) { | 
|  | 6853 | assert(canCombine(ToBeCombined) && "Unsupported instruction to combine"); | 
|  | 6854 | CombineInst = ToBeCombined; | 
|  | 6855 | } | 
|  | 6856 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 6857 | /// Promote all the instructions enqueued for promotion if it is | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6858 | /// is profitable. | 
|  | 6859 | /// \return True if the promotion happened, false otherwise. | 
|  | 6860 | bool promote() { | 
|  | 6861 | // Check if there is something to promote. | 
|  | 6862 | // Right now, if we do not have anything to combine with, | 
|  | 6863 | // we assume the promotion is not profitable. | 
|  | 6864 | if (InstsToBePromoted.empty() || !CombineInst) | 
|  | 6865 | return false; | 
|  | 6866 |  | 
|  | 6867 | // Check cost. | 
|  | 6868 | if (!StressStoreExtract && !isProfitableToPromote()) | 
|  | 6869 | return false; | 
|  | 6870 |  | 
|  | 6871 | // Promote. | 
|  | 6872 | for (auto &ToBePromoted : InstsToBePromoted) | 
|  | 6873 | promoteImpl(ToBePromoted); | 
|  | 6874 | InstsToBePromoted.clear(); | 
|  | 6875 | return true; | 
|  | 6876 | } | 
|  | 6877 | }; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6878 |  | 
|  | 6879 | } // end anonymous namespace | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6880 |  | 
|  | 6881 | void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) { | 
|  | 6882 | // At this point, we know that all the operands of ToBePromoted but Def | 
|  | 6883 | // can be statically promoted. | 
|  | 6884 | // For Def, we need to use its parameter in ToBePromoted: | 
|  | 6885 | // b = ToBePromoted ty1 a | 
|  | 6886 | // Def = Transition ty1 b to ty2 | 
|  | 6887 | // Move the transition down. | 
|  | 6888 | // 1. Replace all uses of the promoted operation by the transition. | 
|  | 6889 | // = ... b => = ... Def. | 
|  | 6890 | assert(ToBePromoted->getType() == Transition->getType() && | 
|  | 6891 | "The type of the result of the transition does not match " | 
|  | 6892 | "the final type"); | 
|  | 6893 | ToBePromoted->replaceAllUsesWith(Transition); | 
|  | 6894 | // 2. Update the type of the uses. | 
|  | 6895 | // b = ToBePromoted ty2 Def => b = ToBePromoted ty1 Def. | 
|  | 6896 | Type *TransitionTy = getTransitionType(); | 
|  | 6897 | ToBePromoted->mutateType(TransitionTy); | 
|  | 6898 | // 3. Update all the operands of the promoted operation with promoted | 
|  | 6899 | // operands. | 
|  | 6900 | // b = ToBePromoted ty1 Def => b = ToBePromoted ty1 a. | 
|  | 6901 | for (Use &U : ToBePromoted->operands()) { | 
|  | 6902 | Value *Val = U.get(); | 
|  | 6903 | Value *NewVal = nullptr; | 
|  | 6904 | if (Val == Transition) | 
|  | 6905 | NewVal = Transition->getOperand(getTransitionOriginalValueIdx()); | 
|  | 6906 | else if (isa<UndefValue>(Val) || isa<ConstantInt>(Val) || | 
|  | 6907 | isa<ConstantFP>(Val)) { | 
|  | 6908 | // Use a splat constant if it is not safe to use undef. | 
|  | 6909 | NewVal = getConstantVector( | 
|  | 6910 | cast<Constant>(Val), | 
|  | 6911 | isa<UndefValue>(Val) || | 
|  | 6912 | canCauseUndefinedBehavior(ToBePromoted, U.getOperandNo())); | 
|  | 6913 | } else | 
| Craig Topper | d3c02f1 | 2015-01-05 10:15:49 +0000 | [diff] [blame] | 6914 | llvm_unreachable("Did you modified shouldPromote and forgot to update " | 
|  | 6915 | "this?"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6916 | ToBePromoted->setOperand(U.getOperandNo(), NewVal); | 
|  | 6917 | } | 
| Sanjay Patel | 674d2c2 | 2017-08-29 14:07:48 +0000 | [diff] [blame] | 6918 | Transition->moveAfter(ToBePromoted); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6919 | Transition->setOperand(getTransitionOriginalValueIdx(), ToBePromoted); | 
|  | 6920 | } | 
|  | 6921 |  | 
|  | 6922 | /// Some targets can do store(extractelement) with one instruction. | 
|  | 6923 | /// Try to push the extractelement towards the stores when the target | 
|  | 6924 | /// has this feature and this is profitable. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 6925 | bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) { | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 6926 | unsigned CombineCost = std::numeric_limits<unsigned>::max(); | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 6927 | if (DisableStoreExtract || | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6928 | (!StressStoreExtract && | 
|  | 6929 | !TLI->canCombineStoreAndExtract(Inst->getOperand(0)->getType(), | 
|  | 6930 | Inst->getOperand(1), CombineCost))) | 
|  | 6931 | return false; | 
|  | 6932 |  | 
|  | 6933 | // At this point we know that Inst is a vector to scalar transition. | 
|  | 6934 | // Try to move it down the def-use chain, until: | 
|  | 6935 | // - We can combine the transition with its single use | 
|  | 6936 | //   => we got rid of the transition. | 
|  | 6937 | // - We escape the current basic block | 
|  | 6938 | //   => we would need to check that we are moving it at a cheaper place and | 
|  | 6939 | //      we do not do that for now. | 
|  | 6940 | BasicBlock *Parent = Inst->getParent(); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6941 | LLVM_DEBUG(dbgs() << "Found an interesting transition: " << *Inst << '\n'); | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 6942 | VectorPromoteHelper VPH(*DL, *TLI, *TTI, Inst, CombineCost); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6943 | // If the transition has more than one use, assume this is not going to be | 
|  | 6944 | // beneficial. | 
|  | 6945 | while (Inst->hasOneUse()) { | 
|  | 6946 | Instruction *ToBePromoted = cast<Instruction>(*Inst->user_begin()); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6947 | LLVM_DEBUG(dbgs() << "Use: " << *ToBePromoted << '\n'); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6948 |  | 
|  | 6949 | if (ToBePromoted->getParent() != Parent) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6950 | LLVM_DEBUG(dbgs() << "Instruction to promote is in a different block (" | 
|  | 6951 | << ToBePromoted->getParent()->getName() | 
|  | 6952 | << ") than the transition (" << Parent->getName() | 
|  | 6953 | << ").\n"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6954 | return false; | 
|  | 6955 | } | 
|  | 6956 |  | 
|  | 6957 | if (VPH.canCombine(ToBePromoted)) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6958 | LLVM_DEBUG(dbgs() << "Assume " << *Inst << '\n' | 
|  | 6959 | << "will be combined with: " << *ToBePromoted << '\n'); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6960 | VPH.recordCombineInstruction(ToBePromoted); | 
|  | 6961 | bool Changed = VPH.promote(); | 
|  | 6962 | NumStoreExtractExposed += Changed; | 
|  | 6963 | return Changed; | 
|  | 6964 | } | 
|  | 6965 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6966 | LLVM_DEBUG(dbgs() << "Try promoting.\n"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6967 | if (!VPH.canPromote(ToBePromoted) || !VPH.shouldPromote(ToBePromoted)) | 
|  | 6968 | return false; | 
|  | 6969 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 6970 | LLVM_DEBUG(dbgs() << "Promoting is possible... Enqueue for promotion!\n"); | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 6971 |  | 
|  | 6972 | VPH.enqueueForPromotion(ToBePromoted); | 
|  | 6973 | Inst = ToBePromoted; | 
|  | 6974 | } | 
|  | 6975 | return false; | 
|  | 6976 | } | 
|  | 6977 |  | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 6978 | /// For the instruction sequence of store below, F and I values | 
|  | 6979 | /// are bundled together as an i64 value before being stored into memory. | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 6980 | /// Sometimes it is more efficient to generate separate stores for F and I, | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 6981 | /// which can remove the bitwise instructions or sink them to colder places. | 
|  | 6982 | /// | 
|  | 6983 | ///   (store (or (zext (bitcast F to i32) to i64), | 
|  | 6984 | ///              (shl (zext I to i64), 32)), addr)  --> | 
|  | 6985 | ///   (store F, addr) and (store I, addr+4) | 
|  | 6986 | /// | 
|  | 6987 | /// Similarly, splitting for other merged store can also be beneficial, like: | 
|  | 6988 | /// For pair of {i32, i32}, i64 store --> two i32 stores. | 
|  | 6989 | /// For pair of {i32, i16}, i64 store --> two i32 stores. | 
|  | 6990 | /// For pair of {i16, i16}, i32 store --> two i16 stores. | 
|  | 6991 | /// For pair of {i16, i8},  i32 store --> two i16 stores. | 
|  | 6992 | /// For pair of {i8, i8},   i16 store --> two i8 stores. | 
|  | 6993 | /// | 
|  | 6994 | /// We allow each target to determine specifically which kind of splitting is | 
|  | 6995 | /// supported. | 
|  | 6996 | /// | 
|  | 6997 | /// The store patterns are commonly seen from the simple code snippet below | 
|  | 6998 | /// if only std::make_pair(...) is sroa transformed before inlined into hoo. | 
|  | 6999 | ///   void goo(const std::pair<int, float> &); | 
|  | 7000 | ///   hoo() { | 
|  | 7001 | ///     ... | 
|  | 7002 | ///     goo(std::make_pair(tmp, ftmp)); | 
|  | 7003 | ///     ... | 
|  | 7004 | ///   } | 
|  | 7005 | /// | 
|  | 7006 | /// Although we already have similar splitting in DAG Combine, we duplicate | 
|  | 7007 | /// it in CodeGenPrepare to catch the case in which pattern is across | 
|  | 7008 | /// multiple BBs. The logic in DAG Combine is kept to catch case generated | 
|  | 7009 | /// during code expansion. | 
|  | 7010 | static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, | 
|  | 7011 | const TargetLowering &TLI) { | 
|  | 7012 | // Handle simple but common cases only. | 
|  | 7013 | Type *StoreType = SI.getValueOperand()->getType(); | 
| Sander de Smalen | 4cf16ef | 2020-01-22 10:42:57 +0000 | [diff] [blame] | 7014 |  | 
|  | 7015 | // The code below assumes shifting a value by <number of bits>, | 
|  | 7016 | // whereas scalable vectors would have to be shifted by | 
|  | 7017 | // <2log(vscale) + number of bits> in order to store the | 
|  | 7018 | // low/high parts. Bailing out for now. | 
| Christopher Tetreault | ccd623e | 2020-04-23 12:45:34 -0700 | [diff] [blame] | 7019 | if (isa<ScalableVectorType>(StoreType)) | 
| Sander de Smalen | 4cf16ef | 2020-01-22 10:42:57 +0000 | [diff] [blame] | 7020 | return false; | 
|  | 7021 |  | 
| Bjorn Pettersson | b477142 | 2019-05-24 09:20:20 +0000 | [diff] [blame] | 7022 | if (!DL.typeSizeEqualsStoreSize(StoreType) || | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7023 | DL.getTypeSizeInBits(StoreType) == 0) | 
|  | 7024 | return false; | 
|  | 7025 |  | 
|  | 7026 | unsigned HalfValBitSize = DL.getTypeSizeInBits(StoreType) / 2; | 
|  | 7027 | Type *SplitStoreType = Type::getIntNTy(SI.getContext(), HalfValBitSize); | 
| Bjorn Pettersson | b477142 | 2019-05-24 09:20:20 +0000 | [diff] [blame] | 7028 | if (!DL.typeSizeEqualsStoreSize(SplitStoreType)) | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7029 | return false; | 
|  | 7030 |  | 
| QingShan Zhang | 0e71a6e | 2019-05-08 07:32:12 +0000 | [diff] [blame] | 7031 | // Don't split the store if it is volatile. | 
|  | 7032 | if (SI.isVolatile()) | 
|  | 7033 | return false; | 
|  | 7034 |  | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7035 | // Match the following patterns: | 
|  | 7036 | // (store (or (zext LValue to i64), | 
|  | 7037 | //            (shl (zext HValue to i64), 32)), HalfValBitSize) | 
|  | 7038 | //  or | 
|  | 7039 | // (store (or (shl (zext HValue to i64), 32)), HalfValBitSize) | 
|  | 7040 | //            (zext LValue to i64), | 
|  | 7041 | // Expect both operands of OR and the first operand of SHL have only | 
|  | 7042 | // one use. | 
|  | 7043 | Value *LValue, *HValue; | 
|  | 7044 | if (!match(SI.getValueOperand(), | 
|  | 7045 | m_c_Or(m_OneUse(m_ZExt(m_Value(LValue))), | 
|  | 7046 | m_OneUse(m_Shl(m_OneUse(m_ZExt(m_Value(HValue))), | 
|  | 7047 | m_SpecificInt(HalfValBitSize)))))) | 
|  | 7048 | return false; | 
|  | 7049 |  | 
|  | 7050 | // Check LValue and HValue are int with size less or equal than 32. | 
|  | 7051 | if (!LValue->getType()->isIntegerTy() || | 
|  | 7052 | DL.getTypeSizeInBits(LValue->getType()) > HalfValBitSize || | 
|  | 7053 | !HValue->getType()->isIntegerTy() || | 
|  | 7054 | DL.getTypeSizeInBits(HValue->getType()) > HalfValBitSize) | 
|  | 7055 | return false; | 
|  | 7056 |  | 
|  | 7057 | // If LValue/HValue is a bitcast instruction, use the EVT before bitcast | 
|  | 7058 | // as the input of target query. | 
|  | 7059 | auto *LBC = dyn_cast<BitCastInst>(LValue); | 
|  | 7060 | auto *HBC = dyn_cast<BitCastInst>(HValue); | 
|  | 7061 | EVT LowTy = LBC ? EVT::getEVT(LBC->getOperand(0)->getType()) | 
|  | 7062 | : EVT::getEVT(LValue->getType()); | 
|  | 7063 | EVT HighTy = HBC ? EVT::getEVT(HBC->getOperand(0)->getType()) | 
|  | 7064 | : EVT::getEVT(HValue->getType()); | 
|  | 7065 | if (!ForceSplitStore && !TLI.isMultiStoresCheaperThanBitsMerge(LowTy, HighTy)) | 
|  | 7066 | return false; | 
|  | 7067 |  | 
|  | 7068 | // Start to split store. | 
|  | 7069 | IRBuilder<> Builder(SI.getContext()); | 
|  | 7070 | Builder.SetInsertPoint(&SI); | 
|  | 7071 |  | 
|  | 7072 | // If LValue/HValue is a bitcast in another BB, create a new one in current | 
|  | 7073 | // BB so it may be merged with the splitted stores by dag combiner. | 
|  | 7074 | if (LBC && LBC->getParent() != SI.getParent()) | 
|  | 7075 | LValue = Builder.CreateBitCast(LBC->getOperand(0), LBC->getType()); | 
|  | 7076 | if (HBC && HBC->getParent() != SI.getParent()) | 
|  | 7077 | HValue = Builder.CreateBitCast(HBC->getOperand(0), HBC->getType()); | 
|  | 7078 |  | 
| Jonas Paulsson | 5612bb2 | 2018-03-13 08:36:20 +0000 | [diff] [blame] | 7079 | bool IsLE = SI.getModule()->getDataLayout().isLittleEndian(); | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7080 | auto CreateSplitStore = [&](Value *V, bool Upper) { | 
|  | 7081 | V = Builder.CreateZExtOrBitCast(V, SplitStoreType); | 
|  | 7082 | Value *Addr = Builder.CreateBitCast( | 
|  | 7083 | SI.getOperand(1), | 
|  | 7084 | SplitStoreType->getPointerTo(SI.getPointerAddressSpace())); | 
| Clement Courbet | 15488ff | 2020-02-10 11:27:53 +0100 | [diff] [blame] | 7085 | const bool IsOffsetStore = (IsLE && Upper) || (!IsLE && !Upper); | 
|  | 7086 | if (IsOffsetStore) | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7087 | Addr = Builder.CreateGEP( | 
|  | 7088 | SplitStoreType, Addr, | 
|  | 7089 | ConstantInt::get(Type::getInt32Ty(SI.getContext()), 1)); | 
| Clement Courbet | 15488ff | 2020-02-10 11:27:53 +0100 | [diff] [blame] | 7090 | MaybeAlign Alignment = SI.getAlign(); | 
|  | 7091 | if (IsOffsetStore && Alignment) { | 
|  | 7092 | // When splitting the store in half, naturally one half will retain the | 
|  | 7093 | // alignment of the original wider store, regardless of whether it was | 
|  | 7094 | // over-aligned or not, while the other will require adjustment. | 
|  | 7095 | Alignment = commonAlignment(Alignment, HalfValBitSize / 8); | 
|  | 7096 | } | 
|  | 7097 | Builder.CreateAlignedStore(V, Addr, Alignment); | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7098 | }; | 
|  | 7099 |  | 
|  | 7100 | CreateSplitStore(LValue, false); | 
|  | 7101 | CreateSplitStore(HValue, true); | 
|  | 7102 |  | 
|  | 7103 | // Delete the old store. | 
|  | 7104 | SI.eraseFromParent(); | 
|  | 7105 | return true; | 
|  | 7106 | } | 
|  | 7107 |  | 
| Hiroshi Yamauchi | 9364432 | 2017-09-11 17:52:08 +0000 | [diff] [blame] | 7108 | // Return true if the GEP has two operands, the first operand is of a sequential | 
|  | 7109 | // type, and the second operand is a constant. | 
|  | 7110 | static bool GEPSequentialConstIndexed(GetElementPtrInst *GEP) { | 
|  | 7111 | gep_type_iterator I = gep_type_begin(*GEP); | 
|  | 7112 | return GEP->getNumOperands() == 2 && | 
|  | 7113 | I.isSequential() && | 
|  | 7114 | isa<ConstantInt>(GEP->getOperand(1)); | 
|  | 7115 | } | 
|  | 7116 |  | 
|  | 7117 | // Try unmerging GEPs to reduce liveness interference (register pressure) across | 
|  | 7118 | // IndirectBr edges. Since IndirectBr edges tend to touch on many blocks, | 
|  | 7119 | // reducing liveness interference across those edges benefits global register | 
|  | 7120 | // allocation. Currently handles only certain cases. | 
|  | 7121 | // | 
|  | 7122 | // For example, unmerge %GEPI and %UGEPI as below. | 
|  | 7123 | // | 
|  | 7124 | // ---------- BEFORE ---------- | 
|  | 7125 | // SrcBlock: | 
|  | 7126 | //   ... | 
|  | 7127 | //   %GEPIOp = ... | 
|  | 7128 | //   ... | 
|  | 7129 | //   %GEPI = gep %GEPIOp, Idx | 
|  | 7130 | //   ... | 
|  | 7131 | //   indirectbr ... [ label %DstB0, label %DstB1, ... label %DstBi ... ] | 
|  | 7132 | //   (* %GEPI is alive on the indirectbr edges due to other uses ahead) | 
|  | 7133 | //   (* %GEPIOp is alive on the indirectbr edges only because of it's used by | 
|  | 7134 | //   %UGEPI) | 
|  | 7135 | // | 
|  | 7136 | // DstB0: ... (there may be a gep similar to %UGEPI to be unmerged) | 
|  | 7137 | // DstB1: ... (there may be a gep similar to %UGEPI to be unmerged) | 
|  | 7138 | // ... | 
|  | 7139 | // | 
|  | 7140 | // DstBi: | 
|  | 7141 | //   ... | 
|  | 7142 | //   %UGEPI = gep %GEPIOp, UIdx | 
|  | 7143 | // ... | 
|  | 7144 | // --------------------------- | 
|  | 7145 | // | 
|  | 7146 | // ---------- AFTER ---------- | 
|  | 7147 | // SrcBlock: | 
|  | 7148 | //   ... (same as above) | 
|  | 7149 | //    (* %GEPI is still alive on the indirectbr edges) | 
|  | 7150 | //    (* %GEPIOp is no longer alive on the indirectbr edges as a result of the | 
|  | 7151 | //    unmerging) | 
|  | 7152 | // ... | 
|  | 7153 | // | 
|  | 7154 | // DstBi: | 
|  | 7155 | //   ... | 
|  | 7156 | //   %UGEPI = gep %GEPI, (UIdx-Idx) | 
|  | 7157 | //   ... | 
|  | 7158 | // --------------------------- | 
|  | 7159 | // | 
|  | 7160 | // The register pressure on the IndirectBr edges is reduced because %GEPIOp is | 
|  | 7161 | // no longer alive on them. | 
|  | 7162 | // | 
|  | 7163 | // We try to unmerge GEPs here in CodGenPrepare, as opposed to limiting merging | 
|  | 7164 | // of GEPs in the first place in InstCombiner::visitGetElementPtrInst() so as | 
|  | 7165 | // not to disable further simplications and optimizations as a result of GEP | 
|  | 7166 | // merging. | 
|  | 7167 | // | 
|  | 7168 | // Note this unmerging may increase the length of the data flow critical path | 
|  | 7169 | // (the path from %GEPIOp to %UGEPI would go through %GEPI), which is a tradeoff | 
|  | 7170 | // between the register pressure and the length of data-flow critical | 
|  | 7171 | // path. Restricting this to the uncommon IndirectBr case would minimize the | 
|  | 7172 | // impact of potentially longer critical path, if any, and the impact on compile | 
|  | 7173 | // time. | 
|  | 7174 | static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI, | 
|  | 7175 | const TargetTransformInfo *TTI) { | 
|  | 7176 | BasicBlock *SrcBlock = GEPI->getParent(); | 
|  | 7177 | // Check that SrcBlock ends with an IndirectBr. If not, give up. The common | 
|  | 7178 | // (non-IndirectBr) cases exit early here. | 
|  | 7179 | if (!isa<IndirectBrInst>(SrcBlock->getTerminator())) | 
|  | 7180 | return false; | 
|  | 7181 | // Check that GEPI is a simple gep with a single constant index. | 
|  | 7182 | if (!GEPSequentialConstIndexed(GEPI)) | 
|  | 7183 | return false; | 
|  | 7184 | ConstantInt *GEPIIdx = cast<ConstantInt>(GEPI->getOperand(1)); | 
|  | 7185 | // Check that GEPI is a cheap one. | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 7186 | if (TTI->getIntImmCost(GEPIIdx->getValue(), GEPIIdx->getType(), | 
|  | 7187 | TargetTransformInfo::TCK_SizeAndLatency) | 
| Hiroshi Yamauchi | 9364432 | 2017-09-11 17:52:08 +0000 | [diff] [blame] | 7188 | > TargetTransformInfo::TCC_Basic) | 
|  | 7189 | return false; | 
|  | 7190 | Value *GEPIOp = GEPI->getOperand(0); | 
|  | 7191 | // Check that GEPIOp is an instruction that's also defined in SrcBlock. | 
|  | 7192 | if (!isa<Instruction>(GEPIOp)) | 
|  | 7193 | return false; | 
|  | 7194 | auto *GEPIOpI = cast<Instruction>(GEPIOp); | 
|  | 7195 | if (GEPIOpI->getParent() != SrcBlock) | 
|  | 7196 | return false; | 
|  | 7197 | // Check that GEP is used outside the block, meaning it's alive on the | 
|  | 7198 | // IndirectBr edge(s). | 
|  | 7199 | if (find_if(GEPI->users(), [&](User *Usr) { | 
|  | 7200 | if (auto *I = dyn_cast<Instruction>(Usr)) { | 
|  | 7201 | if (I->getParent() != SrcBlock) { | 
|  | 7202 | return true; | 
|  | 7203 | } | 
|  | 7204 | } | 
|  | 7205 | return false; | 
|  | 7206 | }) == GEPI->users().end()) | 
|  | 7207 | return false; | 
|  | 7208 | // The second elements of the GEP chains to be unmerged. | 
|  | 7209 | std::vector<GetElementPtrInst *> UGEPIs; | 
|  | 7210 | // Check each user of GEPIOp to check if unmerging would make GEPIOp not alive | 
|  | 7211 | // on IndirectBr edges. | 
|  | 7212 | for (User *Usr : GEPIOp->users()) { | 
|  | 7213 | if (Usr == GEPI) continue; | 
|  | 7214 | // Check if Usr is an Instruction. If not, give up. | 
|  | 7215 | if (!isa<Instruction>(Usr)) | 
|  | 7216 | return false; | 
|  | 7217 | auto *UI = cast<Instruction>(Usr); | 
|  | 7218 | // Check if Usr in the same block as GEPIOp, which is fine, skip. | 
|  | 7219 | if (UI->getParent() == SrcBlock) | 
|  | 7220 | continue; | 
|  | 7221 | // Check if Usr is a GEP. If not, give up. | 
|  | 7222 | if (!isa<GetElementPtrInst>(Usr)) | 
|  | 7223 | return false; | 
|  | 7224 | auto *UGEPI = cast<GetElementPtrInst>(Usr); | 
|  | 7225 | // Check if UGEPI is a simple gep with a single constant index and GEPIOp is | 
|  | 7226 | // the pointer operand to it. If so, record it in the vector. If not, give | 
|  | 7227 | // up. | 
|  | 7228 | if (!GEPSequentialConstIndexed(UGEPI)) | 
|  | 7229 | return false; | 
|  | 7230 | if (UGEPI->getOperand(0) != GEPIOp) | 
|  | 7231 | return false; | 
|  | 7232 | if (GEPIIdx->getType() != | 
|  | 7233 | cast<ConstantInt>(UGEPI->getOperand(1))->getType()) | 
|  | 7234 | return false; | 
|  | 7235 | ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1)); | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 7236 | if (TTI->getIntImmCost(UGEPIIdx->getValue(), UGEPIIdx->getType(), | 
|  | 7237 | TargetTransformInfo::TCK_SizeAndLatency) | 
| Hiroshi Yamauchi | 9364432 | 2017-09-11 17:52:08 +0000 | [diff] [blame] | 7238 | > TargetTransformInfo::TCC_Basic) | 
|  | 7239 | return false; | 
|  | 7240 | UGEPIs.push_back(UGEPI); | 
|  | 7241 | } | 
|  | 7242 | if (UGEPIs.size() == 0) | 
|  | 7243 | return false; | 
|  | 7244 | // Check the materializing cost of (Uidx-Idx). | 
|  | 7245 | for (GetElementPtrInst *UGEPI : UGEPIs) { | 
|  | 7246 | ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1)); | 
|  | 7247 | APInt NewIdx = UGEPIIdx->getValue() - GEPIIdx->getValue(); | 
| Sam Parker | 40574fe | 2020-04-28 14:11:27 +0100 | [diff] [blame] | 7248 | unsigned ImmCost = | 
|  | 7249 | TTI->getIntImmCost(NewIdx, GEPIIdx->getType(), | 
|  | 7250 | TargetTransformInfo::TCK_SizeAndLatency); | 
| Hiroshi Yamauchi | 9364432 | 2017-09-11 17:52:08 +0000 | [diff] [blame] | 7251 | if (ImmCost > TargetTransformInfo::TCC_Basic) | 
|  | 7252 | return false; | 
|  | 7253 | } | 
|  | 7254 | // Now unmerge between GEPI and UGEPIs. | 
|  | 7255 | for (GetElementPtrInst *UGEPI : UGEPIs) { | 
|  | 7256 | UGEPI->setOperand(0, GEPI); | 
|  | 7257 | ConstantInt *UGEPIIdx = cast<ConstantInt>(UGEPI->getOperand(1)); | 
|  | 7258 | Constant *NewUGEPIIdx = | 
|  | 7259 | ConstantInt::get(GEPIIdx->getType(), | 
|  | 7260 | UGEPIIdx->getValue() - GEPIIdx->getValue()); | 
|  | 7261 | UGEPI->setOperand(1, NewUGEPIIdx); | 
|  | 7262 | // If GEPI is not inbounds but UGEPI is inbounds, change UGEPI to not | 
|  | 7263 | // inbounds to avoid UB. | 
|  | 7264 | if (!GEPI->isInBounds()) { | 
|  | 7265 | UGEPI->setIsInBounds(false); | 
|  | 7266 | } | 
|  | 7267 | } | 
|  | 7268 | // After unmerging, verify that GEPIOp is actually only used in SrcBlock (not | 
|  | 7269 | // alive on IndirectBr edges). | 
|  | 7270 | assert(find_if(GEPIOp->users(), [&](User *Usr) { | 
|  | 7271 | return cast<Instruction>(Usr)->getParent() != SrcBlock; | 
|  | 7272 | }) == GEPIOp->users().end() && "GEPIOp is used outside SrcBlock"); | 
|  | 7273 | return true; | 
|  | 7274 | } | 
|  | 7275 |  | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 7276 | bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) { | 
| Ahmed Bougacha | f329914 | 2015-06-17 20:44:32 +0000 | [diff] [blame] | 7277 | // Bail out if we inserted the instruction to prevent optimizations from | 
|  | 7278 | // stepping on each other's toes. | 
|  | 7279 | if (InsertedInsts.count(I)) | 
|  | 7280 | return false; | 
|  | 7281 |  | 
| Sanjay Patel | d1ce455 | 2019-03-20 15:53:06 +0000 | [diff] [blame] | 7282 | // TODO: Move into the switch on opcode below here. | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7283 | if (PHINode *P = dyn_cast<PHINode>(I)) { | 
|  | 7284 | // It is possible for very late stage optimizations (such as SimplifyCFG) | 
|  | 7285 | // to introduce PHI nodes too late to be cleaned up.  If we detect such a | 
|  | 7286 | // trivial PHI, go ahead and zap it here. | 
| Daniel Berlin | 4d0fe64 | 2017-04-28 19:55:38 +0000 | [diff] [blame] | 7287 | if (Value *V = SimplifyInstruction(P, {*DL, TLInfo})) { | 
| Eugene Leviant | 1e249ca | 2019-03-12 10:10:29 +0000 | [diff] [blame] | 7288 | LargeOffsetGEPMap.erase(P); | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7289 | P->replaceAllUsesWith(V); | 
|  | 7290 | P->eraseFromParent(); | 
|  | 7291 | ++NumPHIsElim; | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7292 | return true; | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7293 | } | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7294 | return false; | 
|  | 7295 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7296 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7297 | if (CastInst *CI = dyn_cast<CastInst>(I)) { | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7298 | // If the source of the cast is a constant, then this should have | 
|  | 7299 | // already been constant folded.  The only reason NOT to constant fold | 
|  | 7300 | // it is if something (e.g. LSR) was careful to place the constant | 
|  | 7301 | // evaluation in a block other than then one that uses it (e.g. to hoist | 
|  | 7302 | // the address of globals out of a loop).  If this is the case, we don't | 
|  | 7303 | // want to forward-subst the cast. | 
|  | 7304 | if (isa<Constant>(CI->getOperand(0))) | 
|  | 7305 | return false; | 
|  | 7306 |  | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7307 | if (OptimizeNoopCopyExpression(CI, *TLI, *DL)) | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7308 | return true; | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7309 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7310 | if (isa<ZExtInst>(I) || isa<SExtInst>(I)) { | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 7311 | /// Sink a zext or sext into its user blocks if the target type doesn't | 
|  | 7312 | /// fit in one register | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7313 | if (TLI->getTypeAction(CI->getContext(), | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 7314 | TLI->getValueType(*DL, CI->getType())) == | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7315 | TargetLowering::TypeExpandInteger) { | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 7316 | return SinkCast(CI); | 
|  | 7317 | } else { | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 7318 | bool MadeChange = optimizeExt(I); | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 7319 | return MadeChange | optimizeExtUses(I); | 
| Manuel Jacob | a7c48f9 | 2014-03-13 13:36:25 +0000 | [diff] [blame] | 7320 | } | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7321 | } | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7322 | return false; | 
|  | 7323 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7324 |  | 
| Sanjay Patel | d8b4efc | 2019-02-18 23:33:05 +0000 | [diff] [blame] | 7325 | if (auto *Cmp = dyn_cast<CmpInst>(I)) | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7326 | if (optimizeCmp(Cmp, ModifiedDT)) | 
| Sanjay Patel | 00fcc74 | 2019-02-03 13:48:03 +0000 | [diff] [blame] | 7327 | return true; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7328 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7329 | if (LoadInst *LI = dyn_cast<LoadInst>(I)) { | 
| Sanjoy Das | 0075727 | 2016-12-16 20:29:39 +0000 | [diff] [blame] | 7330 | LI->setMetadata(LLVMContext::MD_invariant_group, nullptr); | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7331 | bool Modified = optimizeLoadExt(LI); | 
|  | 7332 | unsigned AS = LI->getPointerAddressSpace(); | 
|  | 7333 | Modified |= optimizeMemoryInst(I, I->getOperand(0), LI->getType(), AS); | 
|  | 7334 | return Modified; | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7335 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7336 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7337 | if (StoreInst *SI = dyn_cast<StoreInst>(I)) { | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7338 | if (splitMergedValStore(*SI, *DL, *TLI)) | 
| Wei Mi | a2f0b59 | 2016-12-22 19:44:45 +0000 | [diff] [blame] | 7339 | return true; | 
| Sanjoy Das | 0075727 | 2016-12-16 20:29:39 +0000 | [diff] [blame] | 7340 | SI->setMetadata(LLVMContext::MD_invariant_group, nullptr); | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7341 | unsigned AS = SI->getPointerAddressSpace(); | 
|  | 7342 | return optimizeMemoryInst(I, SI->getOperand(1), | 
|  | 7343 | SI->getOperand(0)->getType(), AS); | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7344 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7345 |  | 
| Matt Arsenault | 02d915b | 2017-03-15 22:35:20 +0000 | [diff] [blame] | 7346 | if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { | 
|  | 7347 | unsigned AS = RMW->getPointerAddressSpace(); | 
|  | 7348 | return optimizeMemoryInst(I, RMW->getPointerOperand(), | 
|  | 7349 | RMW->getType(), AS); | 
|  | 7350 | } | 
|  | 7351 |  | 
|  | 7352 | if (AtomicCmpXchgInst *CmpX = dyn_cast<AtomicCmpXchgInst>(I)) { | 
|  | 7353 | unsigned AS = CmpX->getPointerAddressSpace(); | 
|  | 7354 | return optimizeMemoryInst(I, CmpX->getPointerOperand(), | 
|  | 7355 | CmpX->getCompareOperand()->getType(), AS); | 
|  | 7356 | } | 
|  | 7357 |  | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 7358 | BinaryOperator *BinOp = dyn_cast<BinaryOperator>(I); | 
|  | 7359 |  | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7360 | if (BinOp && (BinOp->getOpcode() == Instruction::And) && EnableAndCmpSinking) | 
| Geoff Berry | 5d534b6 | 2017-02-21 18:53:14 +0000 | [diff] [blame] | 7361 | return sinkAndCmp0Expression(BinOp, *TLI, InsertedInsts); | 
|  | 7362 |  | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 7363 | // TODO: Move this into the switch on opcode - it handles shifts already. | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 7364 | if (BinOp && (BinOp->getOpcode() == Instruction::AShr || | 
|  | 7365 | BinOp->getOpcode() == Instruction::LShr)) { | 
|  | 7366 | ConstantInt *CI = dyn_cast<ConstantInt>(BinOp->getOperand(1)); | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7367 | if (CI && TLI->hasExtractBitsInsn()) | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 7368 | if (OptimizeExtractBits(BinOp, CI, *TLI, *DL)) | 
|  | 7369 | return true; | 
| Yi Jiang | d069f63 | 2014-04-21 19:34:27 +0000 | [diff] [blame] | 7370 | } | 
|  | 7371 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7372 | if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) { | 
| Cameron Zwarich | d28c78e | 2011-01-06 02:44:52 +0000 | [diff] [blame] | 7373 | if (GEPI->hasAllZeroIndices()) { | 
|  | 7374 | /// The GEP operand must be a pointer, so must its result -> BitCast | 
|  | 7375 | Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), | 
|  | 7376 | GEPI->getName(), GEPI); | 
| Vedant Kumar | 40399a2 | 2018-05-24 23:00:21 +0000 | [diff] [blame] | 7377 | NC->setDebugLoc(GEPI->getDebugLoc()); | 
| Cameron Zwarich | d28c78e | 2011-01-06 02:44:52 +0000 | [diff] [blame] | 7378 | GEPI->replaceAllUsesWith(NC); | 
|  | 7379 | GEPI->eraseFromParent(); | 
|  | 7380 | ++NumGEPsElim; | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 7381 | optimizeInst(NC, ModifiedDT); | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7382 | return true; | 
| Cameron Zwarich | d28c78e | 2011-01-06 02:44:52 +0000 | [diff] [blame] | 7383 | } | 
| Hiroshi Yamauchi | 9364432 | 2017-09-11 17:52:08 +0000 | [diff] [blame] | 7384 | if (tryUnmergingGEPsAcrossIndirectBr(GEPI, TTI)) { | 
|  | 7385 | return true; | 
|  | 7386 | } | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7387 | return false; | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7388 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 7389 |  | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7390 | if (FreezeInst *FI = dyn_cast<FreezeInst>(I)) { | 
| Juneyoung Lee | 453eac3 | 2020-03-25 16:34:34 +0900 | [diff] [blame] | 7391 | // freeze(icmp a, const)) -> icmp (freeze a), const | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7392 | // This helps generate efficient conditional jumps. | 
| Juneyoung Lee | c39cb1c0 | 2020-03-12 16:34:43 +0900 | [diff] [blame] | 7393 | Instruction *CmpI = nullptr; | 
|  | 7394 | if (ICmpInst *II = dyn_cast<ICmpInst>(FI->getOperand(0))) | 
|  | 7395 | CmpI = II; | 
|  | 7396 | else if (FCmpInst *F = dyn_cast<FCmpInst>(FI->getOperand(0))) | 
|  | 7397 | CmpI = F->getFastMathFlags().none() ? F : nullptr; | 
|  | 7398 |  | 
|  | 7399 | if (CmpI && CmpI->hasOneUse()) { | 
|  | 7400 | auto Op0 = CmpI->getOperand(0), Op1 = CmpI->getOperand(1); | 
|  | 7401 | bool Const0 = isa<ConstantInt>(Op0) || isa<ConstantFP>(Op0) || | 
|  | 7402 | isa<ConstantPointerNull>(Op0); | 
|  | 7403 | bool Const1 = isa<ConstantInt>(Op1) || isa<ConstantFP>(Op1) || | 
|  | 7404 | isa<ConstantPointerNull>(Op1); | 
|  | 7405 | if (Const0 || Const1) { | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7406 | if (!Const0 || !Const1) { | 
| Juneyoung Lee | c39cb1c0 | 2020-03-12 16:34:43 +0900 | [diff] [blame] | 7407 | auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", CmpI); | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7408 | F->takeName(FI); | 
| Juneyoung Lee | c39cb1c0 | 2020-03-12 16:34:43 +0900 | [diff] [blame] | 7409 | CmpI->setOperand(Const0 ? 1 : 0, F); | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7410 | } | 
| Juneyoung Lee | c39cb1c0 | 2020-03-12 16:34:43 +0900 | [diff] [blame] | 7411 | FI->replaceAllUsesWith(CmpI); | 
| Juneyoung Lee | 8eb2f86 | 2020-03-10 01:37:36 +0900 | [diff] [blame] | 7412 | FI->eraseFromParent(); | 
|  | 7413 | return true; | 
|  | 7414 | } | 
|  | 7415 | } | 
|  | 7416 | return false; | 
|  | 7417 | } | 
|  | 7418 |  | 
| Florian Hahn | 3b25196 | 2019-02-05 10:27:40 +0000 | [diff] [blame] | 7419 | if (tryToSinkFreeOperands(I)) | 
|  | 7420 | return true; | 
|  | 7421 |  | 
| Sanjay Patel | d1ce455 | 2019-03-20 15:53:06 +0000 | [diff] [blame] | 7422 | switch (I->getOpcode()) { | 
| Sanjay Patel | c8d88ad1 | 2019-06-16 15:29:03 +0000 | [diff] [blame] | 7423 | case Instruction::Shl: | 
|  | 7424 | case Instruction::LShr: | 
|  | 7425 | case Instruction::AShr: | 
|  | 7426 | return optimizeShiftInst(cast<BinaryOperator>(I)); | 
| Sanjay Patel | d1ce455 | 2019-03-20 15:53:06 +0000 | [diff] [blame] | 7427 | case Instruction::Call: | 
|  | 7428 | return optimizeCallInst(cast<CallInst>(I), ModifiedDT); | 
|  | 7429 | case Instruction::Select: | 
| Teresa Johnson | b7e2138 | 2019-03-27 18:44:25 +0000 | [diff] [blame] | 7430 | return optimizeSelectInst(cast<SelectInst>(I)); | 
| Sanjay Patel | d1ce455 | 2019-03-20 15:53:06 +0000 | [diff] [blame] | 7431 | case Instruction::ShuffleVector: | 
|  | 7432 | return optimizeShuffleVectorInst(cast<ShuffleVectorInst>(I)); | 
|  | 7433 | case Instruction::Switch: | 
|  | 7434 | return optimizeSwitchInst(cast<SwitchInst>(I)); | 
|  | 7435 | case Instruction::ExtractElement: | 
|  | 7436 | return optimizeExtractElementInst(cast<ExtractElementInst>(I)); | 
|  | 7437 | } | 
| Quentin Colombet | c32615d | 2014-10-31 17:52:53 +0000 | [diff] [blame] | 7438 |  | 
| Chris Lattner | ee588de | 2011-01-15 07:29:01 +0000 | [diff] [blame] | 7439 | return false; | 
| Cameron Zwarich | 14ac865 | 2011-01-06 02:37:26 +0000 | [diff] [blame] | 7440 | } | 
|  | 7441 |  | 
| James Molloy | f01488e | 2016-01-15 09:20:19 +0000 | [diff] [blame] | 7442 | /// Given an OR instruction, check to see if this is a bitreverse | 
|  | 7443 | /// idiom. If so, insert the new intrinsic and return true. | 
|  | 7444 | static bool makeBitReverse(Instruction &I, const DataLayout &DL, | 
|  | 7445 | const TargetLowering &TLI) { | 
|  | 7446 | if (!I.getType()->isIntegerTy() || | 
|  | 7447 | !TLI.isOperationLegalOrCustom(ISD::BITREVERSE, | 
|  | 7448 | TLI.getValueType(DL, I.getType(), true))) | 
|  | 7449 | return false; | 
|  | 7450 |  | 
|  | 7451 | SmallVector<Instruction*, 4> Insts; | 
| Chad Rosier | a00df49 | 2016-05-25 16:22:14 +0000 | [diff] [blame] | 7452 | if (!recognizeBSwapOrBitReverseIdiom(&I, false, true, Insts)) | 
| James Molloy | f01488e | 2016-01-15 09:20:19 +0000 | [diff] [blame] | 7453 | return false; | 
|  | 7454 | Instruction *LastInst = Insts.back(); | 
|  | 7455 | I.replaceAllUsesWith(LastInst); | 
|  | 7456 | RecursivelyDeleteTriviallyDeadInstructions(&I); | 
|  | 7457 | return true; | 
|  | 7458 | } | 
|  | 7459 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 7460 | // In this pass we look for GEP and cast instructions that are used | 
|  | 7461 | // across basic blocks and rewrite them to improve basic-block-at-a-time | 
|  | 7462 | // selection. | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 7463 | bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) { | 
| Cameron Zwarich | ce3b930 | 2011-01-06 00:42:50 +0000 | [diff] [blame] | 7464 | SunkAddrs.clear(); | 
| Cameron Zwarich | 5dd2aa2 | 2011-03-02 03:31:46 +0000 | [diff] [blame] | 7465 | bool MadeChange = false; | 
| Eric Christopher | c1ea149 | 2008-09-24 05:32:41 +0000 | [diff] [blame] | 7466 |  | 
| Chris Lattner | 7a27714 | 2011-01-15 07:14:54 +0000 | [diff] [blame] | 7467 | CurInstIterator = BB.begin(); | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 7468 | while (CurInstIterator != BB.end()) { | 
| Teresa Johnson | 3bd4b5a | 2019-03-25 18:38:48 +0000 | [diff] [blame] | 7469 | MadeChange |= optimizeInst(&*CurInstIterator++, ModifiedDT); | 
| Elena Demikhovsky | 87700a7 | 2014-12-28 08:54:45 +0000 | [diff] [blame] | 7470 | if (ModifiedDT) | 
|  | 7471 | return true; | 
|  | 7472 | } | 
| Benjamin Kramer | 455fa35 | 2012-11-23 19:17:06 +0000 | [diff] [blame] | 7473 |  | 
| James Molloy | f01488e | 2016-01-15 09:20:19 +0000 | [diff] [blame] | 7474 | bool MadeBitReverse = true; | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7475 | while (MadeBitReverse) { | 
| James Molloy | f01488e | 2016-01-15 09:20:19 +0000 | [diff] [blame] | 7476 | MadeBitReverse = false; | 
|  | 7477 | for (auto &I : reverse(BB)) { | 
|  | 7478 | if (makeBitReverse(I, *DL, *TLI)) { | 
|  | 7479 | MadeBitReverse = MadeChange = true; | 
|  | 7480 | break; | 
|  | 7481 | } | 
|  | 7482 | } | 
|  | 7483 | } | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 7484 | MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT); | 
| Junmo Park | 7d6c5f1 | 2016-01-28 09:42:39 +0000 | [diff] [blame] | 7485 |  | 
| Chris Lattner | f2836d1 | 2007-03-31 04:06:36 +0000 | [diff] [blame] | 7486 | return MadeChange; | 
|  | 7487 | } | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7488 |  | 
| Jeremy Morse | c93a9b1 | 2019-12-06 11:21:27 +0000 | [diff] [blame] | 7489 | // Some CGP optimizations may move or alter what's computed in a block. Check | 
|  | 7490 | // whether a dbg.value intrinsic could be pointed at a more appropriate operand. | 
|  | 7491 | bool CodeGenPrepare::fixupDbgValue(Instruction *I) { | 
|  | 7492 | assert(isa<DbgValueInst>(I)); | 
|  | 7493 | DbgValueInst &DVI = *cast<DbgValueInst>(I); | 
|  | 7494 |  | 
|  | 7495 | // Does this dbg.value refer to a sunk address calculation? | 
|  | 7496 | Value *Location = DVI.getVariableLocation(); | 
|  | 7497 | WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; | 
|  | 7498 | Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; | 
|  | 7499 | if (SunkAddr) { | 
|  | 7500 | // Point dbg.value at locally computed address, which should give the best | 
|  | 7501 | // opportunity to be accurately lowered. This update may change the type of | 
|  | 7502 | // pointer being referred to; however this makes no difference to debugging | 
|  | 7503 | // information, and we can't generate bitcasts that may affect codegen. | 
|  | 7504 | DVI.setOperand(0, MetadataAsValue::get(DVI.getContext(), | 
|  | 7505 | ValueAsMetadata::get(SunkAddr))); | 
|  | 7506 | return true; | 
|  | 7507 | } | 
|  | 7508 | return false; | 
|  | 7509 | } | 
|  | 7510 |  | 
| Jeremy Morse | 00e2388 | 2019-12-09 11:26:44 +0000 | [diff] [blame] | 7511 | // A llvm.dbg.value may be using a value before its definition, due to | 
|  | 7512 | // optimizations in this pass and others. Scan for such dbg.values, and rescue | 
|  | 7513 | // them by moving the dbg.value to immediately after the value definition. | 
|  | 7514 | // FIXME: Ideally this should never be necessary, and this has the potential | 
|  | 7515 | // to re-order dbg.value intrinsics. | 
| Sanjay Patel | fc580a6 | 2015-09-21 23:03:16 +0000 | [diff] [blame] | 7516 | bool CodeGenPrepare::placeDbgValues(Function &F) { | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7517 | bool MadeChange = false; | 
| Jeremy Morse | 00e2388 | 2019-12-09 11:26:44 +0000 | [diff] [blame] | 7518 | DominatorTree DT(F); | 
|  | 7519 |  | 
| Duncan P. N. Exon Smith | 5914a97 | 2015-01-08 20:44:33 +0000 | [diff] [blame] | 7520 | for (BasicBlock &BB : F) { | 
| Duncan P. N. Exon Smith | 5914a97 | 2015-01-08 20:44:33 +0000 | [diff] [blame] | 7521 | for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) { | 
| Duncan P. N. Exon Smith | d83547a | 2015-10-09 18:44:40 +0000 | [diff] [blame] | 7522 | Instruction *Insn = &*BI++; | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7523 | DbgValueInst *DVI = dyn_cast<DbgValueInst>(Insn); | 
| Jeremy Morse | 00e2388 | 2019-12-09 11:26:44 +0000 | [diff] [blame] | 7524 | if (!DVI) | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7525 | continue; | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7526 |  | 
|  | 7527 | Instruction *VI = dyn_cast_or_null<Instruction>(DVI->getValue()); | 
| Jeremy Morse | 00e2388 | 2019-12-09 11:26:44 +0000 | [diff] [blame] | 7528 |  | 
|  | 7529 | if (!VI || VI->isTerminator()) | 
|  | 7530 | continue; | 
|  | 7531 |  | 
|  | 7532 | // If VI is a phi in a block with an EHPad terminator, we can't insert | 
|  | 7533 | // after it. | 
|  | 7534 | if (isa<PHINode>(VI) && VI->getParent()->getTerminator()->isEHPad()) | 
|  | 7535 | continue; | 
|  | 7536 |  | 
|  | 7537 | // If the defining instruction dominates the dbg.value, we do not need | 
|  | 7538 | // to move the dbg.value. | 
|  | 7539 | if (DT.dominates(VI, DVI)) | 
|  | 7540 | continue; | 
|  | 7541 |  | 
|  | 7542 | LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" | 
|  | 7543 | << *DVI << ' ' << *VI); | 
|  | 7544 | DVI->removeFromParent(); | 
|  | 7545 | if (isa<PHINode>(VI)) | 
|  | 7546 | DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); | 
|  | 7547 | else | 
|  | 7548 | DVI->insertAfter(VI); | 
|  | 7549 | MadeChange = true; | 
|  | 7550 | ++NumDbgValueMoved; | 
| Devang Patel | 53771ba | 2011-08-18 00:50:51 +0000 | [diff] [blame] | 7551 | } | 
|  | 7552 | } | 
|  | 7553 | return MadeChange; | 
|  | 7554 | } | 
| Tim Northover | cea0abb | 2014-03-29 08:22:29 +0000 | [diff] [blame] | 7555 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 7556 | /// Scale down both weights to fit into uint32_t. | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7557 | static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse) { | 
|  | 7558 | uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse; | 
| Eugene Zelenko | 900b633 | 2017-08-29 22:32:07 +0000 | [diff] [blame] | 7559 | uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1; | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7560 | NewTrue = NewTrue / Scale; | 
|  | 7561 | NewFalse = NewFalse / Scale; | 
|  | 7562 | } | 
|  | 7563 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 7564 | /// Some targets prefer to split a conditional branch like: | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7565 | /// \code | 
|  | 7566 | ///   %0 = icmp ne i32 %a, 0 | 
|  | 7567 | ///   %1 = icmp ne i32 %b, 0 | 
|  | 7568 | ///   %or.cond = or i1 %0, %1 | 
|  | 7569 | ///   br i1 %or.cond, label %TrueBB, label %FalseBB | 
|  | 7570 | /// \endcode | 
|  | 7571 | /// into multiple branch instructions like: | 
|  | 7572 | /// \code | 
|  | 7573 | ///   bb1: | 
|  | 7574 | ///     %0 = icmp ne i32 %a, 0 | 
|  | 7575 | ///     br i1 %0, label %TrueBB, label %bb2 | 
|  | 7576 | ///   bb2: | 
|  | 7577 | ///     %1 = icmp ne i32 %b, 0 | 
|  | 7578 | ///     br i1 %1, label %TrueBB, label %FalseBB | 
|  | 7579 | /// \endcode | 
|  | 7580 | /// This usually allows instruction selection to do even further optimizations | 
|  | 7581 | /// and combine the compare with the branch instruction. Currently this is | 
|  | 7582 | /// applied for targets which have "cheap" jump instructions. | 
|  | 7583 | /// | 
|  | 7584 | /// FIXME: Remove the (equivalent?) implementation in SelectionDAG. | 
|  | 7585 | /// | 
| Rong Xu | ce3be45 | 2019-03-08 22:46:18 +0000 | [diff] [blame] | 7586 | bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) { | 
| Fangrui Song | 5a56a25 | 2020-01-30 16:17:43 -0800 | [diff] [blame] | 7587 | if (!TM->Options.EnableFastISel || TLI->isJumpExpensive()) | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7588 | return false; | 
|  | 7589 |  | 
|  | 7590 | bool MadeChange = false; | 
|  | 7591 | for (auto &BB : F) { | 
|  | 7592 | // Does this BB end with the following? | 
|  | 7593 | //   %cond1 = icmp|fcmp|binary instruction ... | 
|  | 7594 | //   %cond2 = icmp|fcmp|binary instruction ... | 
|  | 7595 | //   %cond.or = or|and i1 %cond1, cond2 | 
|  | 7596 | //   br i1 %cond.or label %dest1, label %dest2" | 
|  | 7597 | BinaryOperator *LogicOp; | 
|  | 7598 | BasicBlock *TBB, *FBB; | 
|  | 7599 | if (!match(BB.getTerminator(), m_Br(m_OneUse(m_BinOp(LogicOp)), TBB, FBB))) | 
|  | 7600 | continue; | 
|  | 7601 |  | 
| Sanjay Patel | 4257420 | 2015-09-02 19:23:23 +0000 | [diff] [blame] | 7602 | auto *Br1 = cast<BranchInst>(BB.getTerminator()); | 
|  | 7603 | if (Br1->getMetadata(LLVMContext::MD_unpredictable)) | 
|  | 7604 | continue; | 
|  | 7605 |  | 
| Valentin Churavy | 5c29e8c | 2019-12-14 10:33:30 -0500 | [diff] [blame] | 7606 | // The merging of mostly empty BB can cause a degenerate branch. | 
|  | 7607 | if (TBB == FBB) | 
|  | 7608 | continue; | 
|  | 7609 |  | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7610 | unsigned Opc; | 
| Juergen Ributzka | 8bda738 | 2014-12-09 17:50:10 +0000 | [diff] [blame] | 7611 | Value *Cond1, *Cond2; | 
|  | 7612 | if (match(LogicOp, m_And(m_OneUse(m_Value(Cond1)), | 
|  | 7613 | m_OneUse(m_Value(Cond2))))) | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7614 | Opc = Instruction::And; | 
| Juergen Ributzka | 8bda738 | 2014-12-09 17:50:10 +0000 | [diff] [blame] | 7615 | else if (match(LogicOp, m_Or(m_OneUse(m_Value(Cond1)), | 
|  | 7616 | m_OneUse(m_Value(Cond2))))) | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7617 | Opc = Instruction::Or; | 
|  | 7618 | else | 
|  | 7619 | continue; | 
|  | 7620 |  | 
|  | 7621 | if (!match(Cond1, m_CombineOr(m_Cmp(), m_BinOp())) || | 
|  | 7622 | !match(Cond2, m_CombineOr(m_Cmp(), m_BinOp()))   ) | 
|  | 7623 | continue; | 
|  | 7624 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 7625 | LLVM_DEBUG(dbgs() << "Before branch condition splitting\n"; BB.dump()); | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7626 |  | 
|  | 7627 | // Create a new BB. | 
| Duncan P. N. Exon Smith | a848c47 | 2016-02-21 19:52:15 +0000 | [diff] [blame] | 7628 | auto TmpBB = | 
|  | 7629 | BasicBlock::Create(BB.getContext(), BB.getName() + ".cond.split", | 
|  | 7630 | BB.getParent(), BB.getNextNode()); | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7631 |  | 
|  | 7632 | // Update original basic block by using the first condition directly by the | 
|  | 7633 | // branch instruction and removing the no longer needed and/or instruction. | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7634 | Br1->setCondition(Cond1); | 
|  | 7635 | LogicOp->eraseFromParent(); | 
| Juergen Ributzka | 8bda738 | 2014-12-09 17:50:10 +0000 | [diff] [blame] | 7636 |  | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 7637 | // Depending on the condition we have to either replace the true or the | 
|  | 7638 | // false successor of the original branch instruction. | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7639 | if (Opc == Instruction::And) | 
|  | 7640 | Br1->setSuccessor(0, TmpBB); | 
|  | 7641 | else | 
|  | 7642 | Br1->setSuccessor(1, TmpBB); | 
|  | 7643 |  | 
|  | 7644 | // Fill in the new basic block. | 
|  | 7645 | auto *Br2 = IRBuilder<>(TmpBB).CreateCondBr(Cond2, TBB, FBB); | 
| Juergen Ributzka | 8bda738 | 2014-12-09 17:50:10 +0000 | [diff] [blame] | 7646 | if (auto *I = dyn_cast<Instruction>(Cond2)) { | 
|  | 7647 | I->removeFromParent(); | 
|  | 7648 | I->insertBefore(Br2); | 
|  | 7649 | } | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7650 |  | 
|  | 7651 | // Update PHI nodes in both successors. The original BB needs to be | 
| Hiroshi Inoue | 6a391bb | 2017-06-27 10:35:37 +0000 | [diff] [blame] | 7652 | // replaced in one successor's PHI nodes, because the branch comes now from | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7653 | // the newly generated BB (NewBB). In the other successor we need to add one | 
|  | 7654 | // incoming edge to the PHI nodes, because both branch instructions target | 
|  | 7655 | // now the same successor. Depending on the original branch condition | 
|  | 7656 | // (and/or) we have to swap the successors (TrueDest, FalseDest), so that | 
| Simon Pilgrim | f2fbf43 | 2016-11-20 13:47:59 +0000 | [diff] [blame] | 7657 | // we perform the correct update for the PHI nodes. | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7658 | // This doesn't change the successor order of the just created branch | 
|  | 7659 | // instruction (or any other instruction). | 
|  | 7660 | if (Opc == Instruction::Or) | 
|  | 7661 | std::swap(TBB, FBB); | 
|  | 7662 |  | 
|  | 7663 | // Replace the old BB with the new BB. | 
| Roman Lebedev | 1a1b922 | 2019-05-05 18:59:39 +0000 | [diff] [blame] | 7664 | TBB->replacePhiUsesWith(&BB, TmpBB); | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7665 |  | 
|  | 7666 | // Add another incoming edge form the new BB. | 
| Benjamin Kramer | c7fc81e | 2017-12-30 15:27:33 +0000 | [diff] [blame] | 7667 | for (PHINode &PN : FBB->phis()) { | 
|  | 7668 | auto *Val = PN.getIncomingValueForBlock(&BB); | 
|  | 7669 | PN.addIncoming(Val, TmpBB); | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7670 | } | 
|  | 7671 |  | 
|  | 7672 | // Update the branch weights (from SelectionDAGBuilder:: | 
|  | 7673 | // FindMergedConditions). | 
|  | 7674 | if (Opc == Instruction::Or) { | 
|  | 7675 | // Codegen X | Y as: | 
|  | 7676 | // BB1: | 
|  | 7677 | //   jmp_if_X TBB | 
|  | 7678 | //   jmp TmpBB | 
|  | 7679 | // TmpBB: | 
|  | 7680 | //   jmp_if_Y TBB | 
|  | 7681 | //   jmp FBB | 
|  | 7682 | // | 
|  | 7683 |  | 
|  | 7684 | // We have flexibility in setting Prob for BB1 and Prob for NewBB. | 
|  | 7685 | // The requirement is that | 
|  | 7686 | //   TrueProb for BB1 + (FalseProb for BB1 * TrueProb for TmpBB) | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 7687 | //     = TrueProb for original BB. | 
|  | 7688 | // Assuming the original weights are A and B, one choice is to set BB1's | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7689 | // weights to A and A+2B, and set TmpBB's weights to A and 2B. This choice | 
|  | 7690 | // assumes that | 
|  | 7691 | //   TrueProb for BB1 == FalseProb for BB1 * TrueProb for TmpBB. | 
|  | 7692 | // Another choice is to assume TrueProb for BB1 equals to TrueProb for | 
|  | 7693 | // TmpBB, but the math is more complicated. | 
|  | 7694 | uint64_t TrueWeight, FalseWeight; | 
| Sanjay Patel | dc88bd6 | 2016-04-23 20:01:22 +0000 | [diff] [blame] | 7695 | if (Br1->extractProfMetadata(TrueWeight, FalseWeight)) { | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7696 | uint64_t NewTrueWeight = TrueWeight; | 
|  | 7697 | uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight; | 
|  | 7698 | scaleWeights(NewTrueWeight, NewFalseWeight); | 
|  | 7699 | Br1->setMetadata(LLVMContext::MD_prof, MDBuilder(Br1->getContext()) | 
|  | 7700 | .createBranchWeights(TrueWeight, FalseWeight)); | 
|  | 7701 |  | 
|  | 7702 | NewTrueWeight = TrueWeight; | 
|  | 7703 | NewFalseWeight = 2 * FalseWeight; | 
|  | 7704 | scaleWeights(NewTrueWeight, NewFalseWeight); | 
|  | 7705 | Br2->setMetadata(LLVMContext::MD_prof, MDBuilder(Br2->getContext()) | 
|  | 7706 | .createBranchWeights(TrueWeight, FalseWeight)); | 
|  | 7707 | } | 
|  | 7708 | } else { | 
|  | 7709 | // Codegen X & Y as: | 
|  | 7710 | // BB1: | 
|  | 7711 | //   jmp_if_X TmpBB | 
|  | 7712 | //   jmp FBB | 
|  | 7713 | // TmpBB: | 
|  | 7714 | //   jmp_if_Y TBB | 
|  | 7715 | //   jmp FBB | 
|  | 7716 | // | 
|  | 7717 | //  This requires creation of TmpBB after CurBB. | 
|  | 7718 |  | 
|  | 7719 | // We have flexibility in setting Prob for BB1 and Prob for TmpBB. | 
|  | 7720 | // The requirement is that | 
|  | 7721 | //   FalseProb for BB1 + (TrueProb for BB1 * FalseProb for TmpBB) | 
| Hiroshi Inoue | c73b6d6 | 2018-06-20 05:29:26 +0000 | [diff] [blame] | 7722 | //     = FalseProb for original BB. | 
|  | 7723 | // Assuming the original weights are A and B, one choice is to set BB1's | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7724 | // weights to 2A+B and B, and set TmpBB's weights to 2A and B. This choice | 
|  | 7725 | // assumes that | 
|  | 7726 | //   FalseProb for BB1 == TrueProb for BB1 * FalseProb for TmpBB. | 
|  | 7727 | uint64_t TrueWeight, FalseWeight; | 
| Sanjay Patel | dc88bd6 | 2016-04-23 20:01:22 +0000 | [diff] [blame] | 7728 | if (Br1->extractProfMetadata(TrueWeight, FalseWeight)) { | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7729 | uint64_t NewTrueWeight = 2 * TrueWeight + FalseWeight; | 
|  | 7730 | uint64_t NewFalseWeight = FalseWeight; | 
|  | 7731 | scaleWeights(NewTrueWeight, NewFalseWeight); | 
|  | 7732 | Br1->setMetadata(LLVMContext::MD_prof, MDBuilder(Br1->getContext()) | 
|  | 7733 | .createBranchWeights(TrueWeight, FalseWeight)); | 
|  | 7734 |  | 
|  | 7735 | NewTrueWeight = 2 * TrueWeight; | 
|  | 7736 | NewFalseWeight = FalseWeight; | 
|  | 7737 | scaleWeights(NewTrueWeight, NewFalseWeight); | 
|  | 7738 | Br2->setMetadata(LLVMContext::MD_prof, MDBuilder(Br2->getContext()) | 
|  | 7739 | .createBranchWeights(TrueWeight, FalseWeight)); | 
|  | 7740 | } | 
|  | 7741 | } | 
|  | 7742 |  | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7743 | ModifiedDT = true; | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7744 | MadeChange = true; | 
|  | 7745 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 7746 | LLVM_DEBUG(dbgs() << "After branch condition splitting\n"; BB.dump(); | 
|  | 7747 | TmpBB->dump()); | 
| Juergen Ributzka | c1bbcbb | 2014-12-09 16:36:13 +0000 | [diff] [blame] | 7748 | } | 
|  | 7749 | return MadeChange; | 
|  | 7750 | } |