| OLD | NEW |
| 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// | 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the skeleton of the TargetLowering class, | 10 // This file implements the skeleton of the TargetLowering class, |
| 11 // specifically invoking the appropriate lowering method for a given | 11 // specifically invoking the appropriate lowering method for a given |
| 12 // instruction kind and driving global register allocation. It also | 12 // instruction kind and driving global register allocation. It also |
| 13 // implements the non-deleted instruction iteration in | 13 // implements the non-deleted instruction iteration in |
| 14 // LoweringContext. | 14 // LoweringContext. |
| 15 // | 15 // |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 | 17 |
| 18 #include "llvm/Support/CommandLine.h" | |
| 19 | |
| 20 #include "assembler_ia32.h" | 18 #include "assembler_ia32.h" |
| 21 #include "IceCfg.h" // setError() | 19 #include "IceCfg.h" // setError() |
| 22 #include "IceCfgNode.h" | 20 #include "IceCfgNode.h" |
| 23 #include "IceOperand.h" | 21 #include "IceOperand.h" |
| 24 #include "IceRegAlloc.h" | 22 #include "IceRegAlloc.h" |
| 25 #include "IceTargetLowering.h" | 23 #include "IceTargetLowering.h" |
| 26 #include "IceTargetLoweringX8632.h" | 24 #include "IceTargetLoweringX8632.h" |
| 27 | 25 |
| 28 namespace Ice { | 26 namespace Ice { |
| 29 | 27 |
| 30 namespace { | |
| 31 | |
| 32 // TODO(stichnot): Move this machinery into main.cpp. | |
| 33 namespace cl = llvm::cl; | |
| 34 cl::opt<bool> DoNopInsertion("nop-insertion", cl::desc("Randomly insert NOPs"), | |
| 35 cl::init(false)); | |
| 36 | |
| 37 cl::opt<int> MaxNopsPerInstruction( | |
| 38 "max-nops-per-instruction", | |
| 39 cl::desc("Max number of nops to insert per instruction"), cl::init(1)); | |
| 40 | |
| 41 cl::opt<int> NopProbabilityAsPercentage( | |
| 42 "nop-insertion-percentage", | |
| 43 cl::desc("Nop insertion probability as percentage"), cl::init(10)); | |
| 44 | |
| 45 cl::opt<bool> | |
| 46 CLRandomizeRegisterAllocation("randomize-regalloc", | |
| 47 cl::desc("Randomize register allocation"), | |
| 48 cl::init(false)); | |
| 49 } // end of anonymous namespace | |
| 50 | |
| 51 void LoweringContext::init(CfgNode *N) { | 28 void LoweringContext::init(CfgNode *N) { |
| 52 Node = N; | 29 Node = N; |
| 53 End = getNode()->getInsts().end(); | 30 End = getNode()->getInsts().end(); |
| 54 rewind(); | 31 rewind(); |
| 55 advanceForward(Next); | 32 advanceForward(Next); |
| 56 } | 33 } |
| 57 | 34 |
| 58 void LoweringContext::rewind() { | 35 void LoweringContext::rewind() { |
| 59 Begin = getNode()->getInsts().begin(); | 36 Begin = getNode()->getInsts().begin(); |
| 60 Cur = Begin; | 37 Cur = Begin; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 if (Target == Target_ARM32) | 72 if (Target == Target_ARM32) |
| 96 return IceTargetARM32::create(Func); | 73 return IceTargetARM32::create(Func); |
| 97 if (Target == Target_ARM64) | 74 if (Target == Target_ARM64) |
| 98 return IceTargetARM64::create(Func); | 75 return IceTargetARM64::create(Func); |
| 99 #endif | 76 #endif |
| 100 Func->setError("Unsupported target"); | 77 Func->setError("Unsupported target"); |
| 101 return nullptr; | 78 return nullptr; |
| 102 } | 79 } |
| 103 | 80 |
| 104 TargetLowering::TargetLowering(Cfg *Func) | 81 TargetLowering::TargetLowering(Cfg *Func) |
| 105 : Func(Func), Ctx(Func->getContext()), | 82 : Func(Func), Ctx(Func->getContext()), HasComputedFrame(false), |
| 106 RandomizeRegisterAllocation(CLRandomizeRegisterAllocation), | 83 CallsReturnsTwice(false), StackAdjustment(0), Context(), |
| 107 HasComputedFrame(false), CallsReturnsTwice(false), StackAdjustment(0), | 84 SnapshotStackAdjustment(0) {} |
| 108 Context(), SnapshotStackAdjustment(0) {} | |
| 109 | 85 |
| 110 std::unique_ptr<Assembler> TargetLowering::createAssembler(TargetArch Target, | 86 std::unique_ptr<Assembler> TargetLowering::createAssembler(TargetArch Target, |
| 111 Cfg *Func) { | 87 Cfg *Func) { |
| 112 // These statements can be #ifdef'd to specialize the assembler | 88 // These statements can be #ifdef'd to specialize the assembler |
| 113 // to a subset of the available targets. TODO: use CRTP. | 89 // to a subset of the available targets. TODO: use CRTP. |
| 114 if (Target == Target_X8632) | 90 if (Target == Target_X8632) |
| 115 return std::unique_ptr<Assembler>(new x86::AssemblerX86()); | 91 return std::unique_ptr<Assembler>(new x86::AssemblerX86()); |
| 116 Func->setError("Unsupported target"); | 92 Func->setError("Unsupported target"); |
| 117 return nullptr; | 93 return nullptr; |
| 118 } | 94 } |
| 119 | 95 |
| 120 void TargetLowering::doAddressOpt() { | 96 void TargetLowering::doAddressOpt() { |
| 121 if (llvm::isa<InstLoad>(*Context.getCur())) | 97 if (llvm::isa<InstLoad>(*Context.getCur())) |
| 122 doAddressOptLoad(); | 98 doAddressOptLoad(); |
| 123 else if (llvm::isa<InstStore>(*Context.getCur())) | 99 else if (llvm::isa<InstStore>(*Context.getCur())) |
| 124 doAddressOptStore(); | 100 doAddressOptStore(); |
| 125 Context.advanceCur(); | 101 Context.advanceCur(); |
| 126 Context.advanceNext(); | 102 Context.advanceNext(); |
| 127 } | 103 } |
| 128 | 104 |
| 129 bool TargetLowering::shouldDoNopInsertion() const { return DoNopInsertion; } | |
| 130 | |
| 131 void TargetLowering::doNopInsertion() { | 105 void TargetLowering::doNopInsertion() { |
| 132 Inst *I = Context.getCur(); | 106 Inst *I = Context.getCur(); |
| 133 bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) || | 107 bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) || |
| 134 llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() || | 108 llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() || |
| 135 I->isDeleted(); | 109 I->isDeleted(); |
| 136 if (!ShouldSkip) { | 110 if (!ShouldSkip) { |
| 137 for (int I = 0; I < MaxNopsPerInstruction; ++I) { | 111 int Probability = Ctx->getFlags().getNopProbabilityAsPercentage(); |
| 138 randomlyInsertNop(NopProbabilityAsPercentage / 100.0); | 112 for (int I = 0; I < Ctx->getFlags().getMaxNopsPerInstruction(); ++I) { |
| 113 randomlyInsertNop(Probability / 100.0); |
| 139 } | 114 } |
| 140 } | 115 } |
| 141 } | 116 } |
| 142 | 117 |
| 143 // Lowers a single instruction according to the information in | 118 // Lowers a single instruction according to the information in |
| 144 // Context, by checking the Context.Cur instruction kind and calling | 119 // Context, by checking the Context.Cur instruction kind and calling |
| 145 // the appropriate lowering method. The lowering method should insert | 120 // the appropriate lowering method. The lowering method should insert |
| 146 // target instructions at the Cur.Next insertion point, and should not | 121 // target instructions at the Cur.Next insertion point, and should not |
| 147 // delete the Context.Cur instruction or advance Context.Cur. | 122 // delete the Context.Cur instruction or advance Context.Cur. |
| 148 // | 123 // |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 TimerMarker T(TimerStack::TT_regAlloc, Func); | 219 TimerMarker T(TimerStack::TT_regAlloc, Func); |
| 245 LinearScan LinearScan(Func); | 220 LinearScan LinearScan(Func); |
| 246 RegSetMask RegInclude = RegSet_None; | 221 RegSetMask RegInclude = RegSet_None; |
| 247 RegSetMask RegExclude = RegSet_None; | 222 RegSetMask RegExclude = RegSet_None; |
| 248 RegInclude |= RegSet_CallerSave; | 223 RegInclude |= RegSet_CallerSave; |
| 249 RegInclude |= RegSet_CalleeSave; | 224 RegInclude |= RegSet_CalleeSave; |
| 250 if (hasFramePointer()) | 225 if (hasFramePointer()) |
| 251 RegExclude |= RegSet_FramePointer; | 226 RegExclude |= RegSet_FramePointer; |
| 252 LinearScan.init(Kind); | 227 LinearScan.init(Kind); |
| 253 llvm::SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude); | 228 llvm::SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude); |
| 254 LinearScan.scan(RegMask, RandomizeRegisterAllocation); | 229 LinearScan.scan(RegMask, Ctx->getFlags().shouldRandomizeRegAlloc()); |
| 255 } | 230 } |
| 256 | 231 |
| 257 std::unique_ptr<TargetDataLowering> | 232 std::unique_ptr<TargetDataLowering> |
| 258 TargetDataLowering::createLowering(GlobalContext *Ctx) { | 233 TargetDataLowering::createLowering(GlobalContext *Ctx) { |
| 259 // These statements can be #ifdef'd to specialize the code generator | 234 // These statements can be #ifdef'd to specialize the code generator |
| 260 // to a subset of the available targets. TODO: use CRTP. | 235 // to a subset of the available targets. TODO: use CRTP. |
| 261 TargetArch Target = Ctx->getTargetArch(); | 236 TargetArch Target = Ctx->getFlags().getTargetArch(); |
| 262 if (Target == Target_X8632) | 237 if (Target == Target_X8632) |
| 263 return std::unique_ptr<TargetDataLowering>(TargetDataX8632::create(Ctx)); | 238 return std::unique_ptr<TargetDataLowering>(TargetDataX8632::create(Ctx)); |
| 264 #if 0 | 239 #if 0 |
| 265 if (Target == Target_X8664) | 240 if (Target == Target_X8664) |
| 266 return std::unique_ptr<TargetDataLowering>(TargetDataX8664::create(Ctx)); | 241 return std::unique_ptr<TargetDataLowering>(TargetDataX8664::create(Ctx)); |
| 267 if (Target == Target_ARM32) | 242 if (Target == Target_ARM32) |
| 268 return std::unique_ptr<TargetDataLowering>(TargetDataARM32::create(Ctx)); | 243 return std::unique_ptr<TargetDataLowering>(TargetDataARM32::create(Ctx)); |
| 269 if (Target == Target_ARM64) | 244 if (Target == Target_ARM64) |
| 270 return std::unique_ptr<TargetDataLowering>(TargetDataARM64::create(Ctx)); | 245 return std::unique_ptr<TargetDataLowering>(TargetDataARM64::create(Ctx)); |
| 271 #endif | 246 #endif |
| 272 llvm_unreachable("Unsupported target"); | 247 llvm_unreachable("Unsupported target"); |
| 273 return nullptr; | 248 return nullptr; |
| 274 } | 249 } |
| 275 | 250 |
| 276 TargetDataLowering::~TargetDataLowering() {} | 251 TargetDataLowering::~TargetDataLowering() {} |
| 277 | 252 |
| 278 } // end of namespace Ice | 253 } // end of namespace Ice |
| OLD | NEW |