Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 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 // This file declares the TargetLoweringX8632 class, which | 10 // This file declares the TargetLoweringX8632 class, which |
| 11 // implements the TargetLowering interface for the x86-32 | 11 // implements the TargetLowering interface for the x86-32 |
| 12 // architecture. | 12 // architecture. |
| 13 // | 13 // |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| 17 #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 17 #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| 18 | 18 |
| 19 #include <unordered_map> | |
| 20 | |
| 19 #include "assembler_ia32.h" | 21 #include "assembler_ia32.h" |
| 20 #include "IceDefs.h" | 22 #include "IceDefs.h" |
| 23 #include "IceInst.h" | |
| 21 #include "IceInstX8632.h" | 24 #include "IceInstX8632.h" |
| 22 #include "IceRegistersX8632.h" | 25 #include "IceRegistersX8632.h" |
| 23 #include "IceTargetLowering.h" | 26 #include "IceTargetLowering.h" |
| 24 | 27 |
| 25 namespace Ice { | 28 namespace Ice { |
| 26 | 29 |
| 30 class BoolFoldingEntry { | |
| 31 BoolFoldingEntry(const BoolFoldingEntry &) = delete; | |
| 32 | |
| 33 public: | |
| 34 BoolFoldingEntry() | |
| 35 : Instr(nullptr), IsComplex(false), IsLiveOut(true), NumUses(0) {} | |
| 36 explicit BoolFoldingEntry(Inst *I); | |
| 37 BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default; | |
| 38 // Instr is the instruction producing the i1-type variable of interest. | |
| 39 Inst *Instr; | |
| 40 // IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr). | |
| 41 bool IsComplex; | |
| 42 // IsLiveOut is initialized conservatively to true, and is set to false when | |
| 43 // we encounter an instruction that ends Var's live range. We disable the | |
| 44 // folding optimization when Var is live beyond this basic block. Note that | |
| 45 // if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will | |
| 46 // always be true and the folding optimization will never be performed. | |
| 47 bool IsLiveOut; | |
| 48 // NumUses counts the number of times Var is used as a source operand in the | |
| 49 // basic block. If IsComplex is true and there is more than one use of Var, | |
| 50 // then the folding optimization is disabled for Var. | |
| 51 uint32_t NumUses; | |
| 52 }; | |
| 53 | |
| 54 class BoolFolding { | |
| 55 public: | |
| 56 enum BoolFoldingProducerKind { | |
| 57 PK_None, | |
| 58 PK_Icmp32, | |
| 59 PK_Icmp64, | |
| 60 PK_Fcmp, | |
| 61 PK_Trunc | |
| 62 }; | |
| 63 | |
| 64 // Currently the actual enum values are not used (other than CK_None), but we | |
| 65 // go | |
| 66 // ahead and produce them anyway for symmetry with the | |
| 67 // BoolFoldingProducerKind. | |
| 68 enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext }; | |
|
jvoung (off chromium)
2015/05/17 16:38:16
Just some random thoughts as I was catching up on
| |
| 69 | |
| 70 private: | |
| 71 BoolFolding(const BoolFolding &) = delete; | |
| 72 BoolFolding &operator=(const BoolFolding &) = delete; | |
| 73 | |
| 74 public: | |
| 75 BoolFolding() {} | |
| 76 static BoolFoldingProducerKind getProducerKind(const Inst *Instr); | |
| 77 static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr); | |
| 78 static bool hasComplexLowering(const Inst *Instr); | |
| 79 void init(CfgNode *Node); | |
| 80 const Inst *getProducerFor(const Operand *Opnd) const; | |
| 81 void dump(const Cfg *Func) const; | |
| 82 | |
| 83 private: | |
| 84 // Returns true if Producers contains a valid entry for the given VarNum. | |
| 85 bool containsValid(SizeT VarNum) const { | |
| 86 auto Element = Producers.find(VarNum); | |
| 87 return Element != Producers.end() && Element->second.Instr != nullptr; | |
| 88 } | |
| 89 void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; } | |
| 90 // Producers maps Variable::Number to a BoolFoldingEntry. | |
| 91 std::unordered_map<SizeT, BoolFoldingEntry> Producers; | |
| 92 }; | |
| 93 | |
| 27 class TargetX8632 : public TargetLowering { | 94 class TargetX8632 : public TargetLowering { |
| 28 TargetX8632() = delete; | 95 TargetX8632() = delete; |
| 29 TargetX8632(const TargetX8632 &) = delete; | 96 TargetX8632(const TargetX8632 &) = delete; |
| 30 TargetX8632 &operator=(const TargetX8632 &) = delete; | 97 TargetX8632 &operator=(const TargetX8632 &) = delete; |
| 31 | 98 |
| 32 public: | 99 public: |
| 33 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } | 100 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } |
| 34 | 101 |
| 35 void translateOm1() override; | 102 void translateOm1() override; |
| 36 void translateO2() override; | 103 void translateO2() override; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 56 void emitVariable(const Variable *Var) const override; | 123 void emitVariable(const Variable *Var) const override; |
| 57 | 124 |
| 58 const char *getConstantPrefix() const final { return "$"; } | 125 const char *getConstantPrefix() const final { return "$"; } |
| 59 void emit(const ConstantUndef *C) const final; | 126 void emit(const ConstantUndef *C) const final; |
| 60 void emit(const ConstantInteger32 *C) const final; | 127 void emit(const ConstantInteger32 *C) const final; |
| 61 void emit(const ConstantInteger64 *C) const final; | 128 void emit(const ConstantInteger64 *C) const final; |
| 62 void emit(const ConstantFloat *C) const final; | 129 void emit(const ConstantFloat *C) const final; |
| 63 void emit(const ConstantDouble *C) const final; | 130 void emit(const ConstantDouble *C) const final; |
| 64 | 131 |
| 65 void lowerArguments() override; | 132 void lowerArguments() override; |
| 133 void initNodeForLowering(CfgNode *Node) override; | |
| 66 void addProlog(CfgNode *Node) override; | 134 void addProlog(CfgNode *Node) override; |
| 67 void addEpilog(CfgNode *Node) override; | 135 void addEpilog(CfgNode *Node) override; |
| 68 // Ensure that a 64-bit Variable has been split into 2 32-bit | 136 // Ensure that a 64-bit Variable has been split into 2 32-bit |
| 69 // Variables, creating them if necessary. This is needed for all | 137 // Variables, creating them if necessary. This is needed for all |
| 70 // I64 operations, and it is needed for pushing F64 arguments for | 138 // I64 operations, and it is needed for pushing F64 arguments for |
| 71 // function calls using the 32-bit push instruction (though the | 139 // function calls using the 32-bit push instruction (though the |
| 72 // latter could be done by directly writing to the stack). | 140 // latter could be done by directly writing to the stack). |
| 73 void split64(Variable *Var); | 141 void split64(Variable *Var); |
| 74 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 142 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 75 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 143 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 Legal_None = 0, | 218 Legal_None = 0, |
| 151 Legal_Reg = 1 << 0, // physical register, not stack location | 219 Legal_Reg = 1 << 0, // physical register, not stack location |
| 152 Legal_Imm = 1 << 1, | 220 Legal_Imm = 1 << 1, |
| 153 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 221 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
| 154 Legal_All = ~Legal_None | 222 Legal_All = ~Legal_None |
| 155 }; | 223 }; |
| 156 typedef uint32_t LegalMask; | 224 typedef uint32_t LegalMask; |
| 157 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 225 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 158 int32_t RegNum = Variable::NoRegister); | 226 int32_t RegNum = Variable::NoRegister); |
| 159 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 227 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 228 // Legalize the first source operand for use in the cmp instruction. | |
| 229 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | |
| 160 // Turn a pointer operand into a memory operand that can be | 230 // Turn a pointer operand into a memory operand that can be |
| 161 // used by a real load/store operation. Legalizes the operand as well. | 231 // used by a real load/store operation. Legalizes the operand as well. |
| 162 // This is a nop if the operand is already a legal memory operand. | 232 // This is a nop if the operand is already a legal memory operand. |
| 163 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty); | 233 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty); |
| 164 | 234 |
| 165 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 235 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 166 static Type stackSlotType(); | 236 static Type stackSlotType(); |
| 167 | 237 |
| 168 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 238 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 169 | 239 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 size_t FrameSizeLocals; | 570 size_t FrameSizeLocals; |
| 501 size_t SpillAreaSizeBytes; | 571 size_t SpillAreaSizeBytes; |
| 502 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 572 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 503 llvm::SmallBitVector ScratchRegs; | 573 llvm::SmallBitVector ScratchRegs; |
| 504 llvm::SmallBitVector RegsUsed; | 574 llvm::SmallBitVector RegsUsed; |
| 505 VarList PhysicalRegisters[IceType_NUM]; | 575 VarList PhysicalRegisters[IceType_NUM]; |
| 506 static IceString RegNames[]; | 576 static IceString RegNames[]; |
| 507 | 577 |
| 508 private: | 578 private: |
| 509 ~TargetX8632() override {} | 579 ~TargetX8632() override {} |
| 580 BoolFolding FoldingInfo; | |
| 510 }; | 581 }; |
| 511 | 582 |
| 512 class TargetDataX8632 : public TargetDataLowering { | 583 class TargetDataX8632 : public TargetDataLowering { |
| 513 TargetDataX8632() = delete; | 584 TargetDataX8632() = delete; |
| 514 TargetDataX8632(const TargetDataX8632 &) = delete; | 585 TargetDataX8632(const TargetDataX8632 &) = delete; |
| 515 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; | 586 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; |
| 516 | 587 |
| 517 public: | 588 public: |
| 518 static TargetDataLowering *create(GlobalContext *Ctx) { | 589 static TargetDataLowering *create(GlobalContext *Ctx) { |
| 519 return new TargetDataX8632(Ctx); | 590 return new TargetDataX8632(Ctx); |
| 520 } | 591 } |
| 521 | 592 |
| 522 void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final; | 593 void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final; |
| 523 void lowerConstants() const final; | 594 void lowerConstants() const final; |
| 524 | 595 |
| 525 protected: | 596 protected: |
| 526 explicit TargetDataX8632(GlobalContext *Ctx); | 597 explicit TargetDataX8632(GlobalContext *Ctx); |
| 527 | 598 |
| 528 private: | 599 private: |
| 529 void lowerGlobal(const VariableDeclaration &Var) const; | 600 void lowerGlobal(const VariableDeclaration &Var) const; |
| 530 ~TargetDataX8632() override {} | 601 ~TargetDataX8632() override {} |
| 531 template <typename T> static void emitConstantPool(GlobalContext *Ctx); | 602 template <typename T> static void emitConstantPool(GlobalContext *Ctx); |
| 532 }; | 603 }; |
| 533 | 604 |
| 534 } // end of namespace Ice | 605 } // end of namespace Ice |
| 535 | 606 |
| 536 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 607 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| OLD | NEW |