OLD | NEW |
1 //===- subzero/src/IceTargetLoweringMIPS32.h - MIPS32 lowering ---*- C++-*-===// | 1 //===- subzero/src/IceTargetLoweringMIPS32.h - MIPS32 lowering ---*- C++-*-===// |
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 /// \file | 10 /// \file |
(...skipping 28 matching lines...) Expand all Loading... |
39 return false; | 39 return false; |
40 } | 40 } |
41 static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) { | 41 static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) { |
42 return makeUnique<TargetMIPS32>(Func); | 42 return makeUnique<TargetMIPS32>(Func); |
43 } | 43 } |
44 | 44 |
45 std::unique_ptr<::Ice::Assembler> createAssembler() const override { | 45 std::unique_ptr<::Ice::Assembler> createAssembler() const override { |
46 return makeUnique<MIPS32::AssemblerMIPS32>(); | 46 return makeUnique<MIPS32::AssemblerMIPS32>(); |
47 } | 47 } |
48 | 48 |
| 49 void initNodeForLowering(CfgNode *Node) override { |
| 50 Computations.forgetProducers(); |
| 51 Computations.recordProducers(Node); |
| 52 Computations.dump(Func); |
| 53 } |
| 54 |
49 void translateOm1() override; | 55 void translateOm1() override; |
50 void translateO2() override; | 56 void translateO2() override; |
51 bool doBranchOpt(Inst *Instr, const CfgNode *NextNode) override; | 57 bool doBranchOpt(Inst *Instr, const CfgNode *NextNode) override; |
52 | 58 |
53 SizeT getNumRegisters() const override { return RegMIPS32::Reg_NUM; } | 59 SizeT getNumRegisters() const override { return RegMIPS32::Reg_NUM; } |
54 Variable *getPhysicalRegister(RegNumT RegNum, | 60 Variable *getPhysicalRegister(RegNumT RegNum, |
55 Type Ty = IceType_void) override; | 61 Type Ty = IceType_void) override; |
56 const char *getRegName(RegNumT RegNum, Type Ty) const override; | 62 const char *getRegName(RegNumT RegNum, Type Ty) const override; |
57 SmallBitVector getRegisterSet(RegSetMask Include, | 63 SmallBitVector getRegisterSet(RegSetMask Include, |
58 RegSetMask Exclude) const override; | 64 RegSetMask Exclude) const override; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 void _addu(Variable *Dest, Variable *Src0, Variable *Src1) { | 151 void _addu(Variable *Dest, Variable *Src0, Variable *Src1) { |
146 Context.insert<InstMIPS32Addu>(Dest, Src0, Src1); | 152 Context.insert<InstMIPS32Addu>(Dest, Src0, Src1); |
147 } | 153 } |
148 | 154 |
149 void _and(Variable *Dest, Variable *Src0, Variable *Src1) { | 155 void _and(Variable *Dest, Variable *Src0, Variable *Src1) { |
150 Context.insert<InstMIPS32And>(Dest, Src0, Src1); | 156 Context.insert<InstMIPS32And>(Dest, Src0, Src1); |
151 } | 157 } |
152 | 158 |
153 void _br(CfgNode *Target) { Context.insert<InstMIPS32Br>(Target); } | 159 void _br(CfgNode *Target) { Context.insert<InstMIPS32Br>(Target); } |
154 | 160 |
| 161 void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, Operand *Src0, |
| 162 Operand *Src1, CondMIPS32::Cond Condition) { |
| 163 Context.insert<InstMIPS32Br>(TargetTrue, TargetFalse, Src0, Src1, |
| 164 Condition); |
| 165 } |
| 166 |
155 void _ret(Variable *RA, Variable *Src0 = nullptr) { | 167 void _ret(Variable *RA, Variable *Src0 = nullptr) { |
156 Context.insert<InstMIPS32Ret>(RA, Src0); | 168 Context.insert<InstMIPS32Ret>(RA, Src0); |
157 } | 169 } |
158 | 170 |
159 void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) { | 171 void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) { |
160 Context.insert<InstMIPS32Addiu>(Dest, Src, Imm); | 172 Context.insert<InstMIPS32Addiu>(Dest, Src, Imm); |
161 } | 173 } |
162 | 174 |
163 void _lui(Variable *Dest, uint32_t Imm) { | 175 void _lui(Variable *Dest, uint32_t Imm) { |
164 Context.insert<InstMIPS32Lui>(Dest, Imm); | 176 Context.insert<InstMIPS32Lui>(Dest, Imm); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 bool UsesFramePointer = false; | 354 bool UsesFramePointer = false; |
343 bool NeedsStackAlignment = false; | 355 bool NeedsStackAlignment = false; |
344 static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM]; | 356 static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM]; |
345 static SmallBitVector TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 357 static SmallBitVector TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
346 static SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM]; | 358 static SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM]; |
347 SmallBitVector RegsUsed; | 359 SmallBitVector RegsUsed; |
348 VarList PhysicalRegisters[IceType_NUM]; | 360 VarList PhysicalRegisters[IceType_NUM]; |
349 | 361 |
350 private: | 362 private: |
351 ENABLE_MAKE_UNIQUE; | 363 ENABLE_MAKE_UNIQUE; |
| 364 |
| 365 class ComputationTracker { |
| 366 public: |
| 367 ComputationTracker() = default; |
| 368 ~ComputationTracker() = default; |
| 369 |
| 370 void forgetProducers() { KnownComputations.clear(); } |
| 371 void recordProducers(CfgNode *Node); |
| 372 |
| 373 const Inst *getProducerOf(const Operand *Opnd) const { |
| 374 auto *Var = llvm::dyn_cast<Variable>(Opnd); |
| 375 if (Var == nullptr) { |
| 376 return nullptr; |
| 377 } |
| 378 |
| 379 auto Iter = KnownComputations.find(Var->getIndex()); |
| 380 if (Iter == KnownComputations.end()) { |
| 381 return nullptr; |
| 382 } |
| 383 |
| 384 return Iter->second.Instr; |
| 385 } |
| 386 |
| 387 void dump(const Cfg *Func) const { |
| 388 if (!BuildDefs::dump() || !Func->isVerbose(IceV_Folding)) |
| 389 return; |
| 390 OstreamLocker L(Func->getContext()); |
| 391 Ostream &Str = Func->getContext()->getStrDump(); |
| 392 Str << "foldable producer:\n"; |
| 393 for (const auto &Computation : KnownComputations) { |
| 394 Str << " "; |
| 395 Computation.second.Instr->dump(Func); |
| 396 Str << "\n"; |
| 397 } |
| 398 Str << "\n"; |
| 399 } |
| 400 |
| 401 private: |
| 402 class ComputationEntry { |
| 403 public: |
| 404 ComputationEntry(Inst *I, Type Ty) : Instr(I), ComputationType(Ty) {} |
| 405 Inst *const Instr; |
| 406 // Boolean folding is disabled for variables whose live range is multi |
| 407 // block. We conservatively initialize IsLiveOut to true, and set it to |
| 408 // false once we find the end of the live range for the variable defined |
| 409 // by this instruction. If liveness analysis is not performed (e.g., in |
| 410 // Om1 mode) IsLiveOut will never be set to false, and folding will be |
| 411 // disabled. |
| 412 bool IsLiveOut = true; |
| 413 int32_t NumUses = 0; |
| 414 Type ComputationType; |
| 415 }; |
| 416 |
| 417 // ComputationMap maps a Variable number to a payload identifying which |
| 418 // instruction defined it. |
| 419 using ComputationMap = CfgUnorderedMap<SizeT, ComputationEntry>; |
| 420 ComputationMap KnownComputations; |
| 421 }; |
| 422 |
| 423 ComputationTracker Computations; |
352 }; | 424 }; |
353 | 425 |
354 class TargetDataMIPS32 final : public TargetDataLowering { | 426 class TargetDataMIPS32 final : public TargetDataLowering { |
355 TargetDataMIPS32() = delete; | 427 TargetDataMIPS32() = delete; |
356 TargetDataMIPS32(const TargetDataMIPS32 &) = delete; | 428 TargetDataMIPS32(const TargetDataMIPS32 &) = delete; |
357 TargetDataMIPS32 &operator=(const TargetDataMIPS32 &) = delete; | 429 TargetDataMIPS32 &operator=(const TargetDataMIPS32 &) = delete; |
358 | 430 |
359 public: | 431 public: |
360 static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) { | 432 static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) { |
361 return std::unique_ptr<TargetDataLowering>(new TargetDataMIPS32(Ctx)); | 433 return std::unique_ptr<TargetDataLowering>(new TargetDataMIPS32(Ctx)); |
(...skipping 28 matching lines...) Expand all Loading... |
390 explicit TargetHeaderMIPS32(GlobalContext *Ctx); | 462 explicit TargetHeaderMIPS32(GlobalContext *Ctx); |
391 | 463 |
392 private: | 464 private: |
393 ~TargetHeaderMIPS32() = default; | 465 ~TargetHeaderMIPS32() = default; |
394 }; | 466 }; |
395 | 467 |
396 } // end of namespace MIPS32 | 468 } // end of namespace MIPS32 |
397 } // end of namespace Ice | 469 } // end of namespace Ice |
398 | 470 |
399 #endif // SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H | 471 #endif // SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H |
OLD | NEW |