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 enum BoolFoldingProducerKind { | |
jvoung (off chromium)
2015/05/15 21:48:20
Can these be scoped in the TargetX8632 vs Ice, or
Jim Stichnoth
2015/05/16 17:32:50
It should probably be reasonable to refactor later
| |
31 PK_None, | |
32 PK_Icmp32, | |
33 PK_Icmp64, | |
34 PK_Fcmp, | |
35 PK_Trunc | |
36 }; | |
37 | |
38 // Currently the actual enum values are not used (other than CK_None), but we go | |
39 // ahead and produce them anyway for symmetry with the BoolFoldingProducerKind. | |
40 enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext }; | |
41 | |
42 class BoolFoldingEntry { | |
43 BoolFoldingEntry(const BoolFoldingEntry &) = delete; | |
44 | |
45 public: | |
46 BoolFoldingEntry() | |
47 : Var(nullptr), Instr(nullptr), IsComplex(false), IsLiveOut(true), | |
48 NumUses(0) {} | |
49 explicit BoolFoldingEntry(Inst *I); | |
50 BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default; | |
51 // Var is the i1-type variable produced by the instruction. | |
52 const Variable *Var; | |
jvoung (off chromium)
2015/05/15 21:48:20
Is the Var field used? Could the user just get it
Jim Stichnoth
2015/05/16 17:32:50
Good point, done.
| |
53 // Instr is the instruction whose dest is Var. | |
54 Inst *Instr; | |
55 // IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr). | |
56 bool IsComplex; | |
57 // IsLiveOut is initialized conservatively to true, and is set to false when | |
58 // we encounter an instruction that ends Var's live range. We disable the | |
59 // folding optimization when Var is live beyond this basic block. Note that | |
60 // if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will | |
61 // always be true and the folding optimization will never be performed. | |
62 bool IsLiveOut; | |
63 // NumUses counts the number of times Var is used as a source operand in the | |
64 // basic block. If IsComplex is true and there is more than one use of Var, | |
65 // then the folding optimization is disabled for Var. | |
66 uint32_t NumUses; | |
67 }; | |
68 | |
69 class BoolFolding { | |
70 BoolFolding(const BoolFolding &) = delete; | |
71 BoolFolding &operator=(const BoolFolding &) = delete; | |
72 | |
73 public: | |
74 BoolFolding() {} | |
75 static BoolFoldingProducerKind getProducerKind(const Inst *Instr); | |
76 static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr); | |
77 static bool hasComplexLowering(const Inst *Instr); | |
78 void init(CfgNode *Node); | |
79 const Inst *getProducerFor(const Operand *Opnd) const; | |
80 void dump(const Cfg *Func) const; | |
81 | |
82 private: | |
83 // Returns true if Producers contains a valid entry for the given VarNum. | |
84 bool containsValid(SizeT VarNum) const { | |
85 return Producers.find(VarNum) != Producers.end() && | |
jvoung (off chromium)
2015/05/15 21:48:20
Would a compiler optimize the two lookups find() f
Jim Stichnoth
2015/05/16 17:32:50
Probably, but the hand-"optimized" version is prob
| |
86 Producers.at(VarNum).Instr != nullptr; | |
87 } | |
88 void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; } | |
89 // Producers maps Variable::Number to a BoolFoldingEntry. | |
90 std::unordered_map<SizeT, BoolFoldingEntry> Producers; | |
91 }; | |
92 | |
27 class TargetX8632 : public TargetLowering { | 93 class TargetX8632 : public TargetLowering { |
28 TargetX8632() = delete; | 94 TargetX8632() = delete; |
29 TargetX8632(const TargetX8632 &) = delete; | 95 TargetX8632(const TargetX8632 &) = delete; |
30 TargetX8632 &operator=(const TargetX8632 &) = delete; | 96 TargetX8632 &operator=(const TargetX8632 &) = delete; |
31 | 97 |
32 public: | 98 public: |
33 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } | 99 static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } |
34 | 100 |
35 void translateOm1() override; | 101 void translateOm1() override; |
36 void translateO2() override; | 102 void translateO2() override; |
(...skipping 19 matching lines...) Expand all Loading... | |
56 void emitVariable(const Variable *Var) const override; | 122 void emitVariable(const Variable *Var) const override; |
57 | 123 |
58 const char *getConstantPrefix() const final { return "$"; } | 124 const char *getConstantPrefix() const final { return "$"; } |
59 void emit(const ConstantUndef *C) const final; | 125 void emit(const ConstantUndef *C) const final; |
60 void emit(const ConstantInteger32 *C) const final; | 126 void emit(const ConstantInteger32 *C) const final; |
61 void emit(const ConstantInteger64 *C) const final; | 127 void emit(const ConstantInteger64 *C) const final; |
62 void emit(const ConstantFloat *C) const final; | 128 void emit(const ConstantFloat *C) const final; |
63 void emit(const ConstantDouble *C) const final; | 129 void emit(const ConstantDouble *C) const final; |
64 | 130 |
65 void lowerArguments() override; | 131 void lowerArguments() override; |
132 void initNodeForLowering(CfgNode *Node) override; | |
66 void addProlog(CfgNode *Node) override; | 133 void addProlog(CfgNode *Node) override; |
67 void addEpilog(CfgNode *Node) override; | 134 void addEpilog(CfgNode *Node) override; |
68 // Ensure that a 64-bit Variable has been split into 2 32-bit | 135 // Ensure that a 64-bit Variable has been split into 2 32-bit |
69 // Variables, creating them if necessary. This is needed for all | 136 // Variables, creating them if necessary. This is needed for all |
70 // I64 operations, and it is needed for pushing F64 arguments for | 137 // I64 operations, and it is needed for pushing F64 arguments for |
71 // function calls using the 32-bit push instruction (though the | 138 // function calls using the 32-bit push instruction (though the |
72 // latter could be done by directly writing to the stack). | 139 // latter could be done by directly writing to the stack). |
73 void split64(Variable *Var); | 140 void split64(Variable *Var); |
74 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 141 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
75 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 142 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 size_t FrameSizeLocals; | 567 size_t FrameSizeLocals; |
501 size_t SpillAreaSizeBytes; | 568 size_t SpillAreaSizeBytes; |
502 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 569 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
503 llvm::SmallBitVector ScratchRegs; | 570 llvm::SmallBitVector ScratchRegs; |
504 llvm::SmallBitVector RegsUsed; | 571 llvm::SmallBitVector RegsUsed; |
505 VarList PhysicalRegisters[IceType_NUM]; | 572 VarList PhysicalRegisters[IceType_NUM]; |
506 static IceString RegNames[]; | 573 static IceString RegNames[]; |
507 | 574 |
508 private: | 575 private: |
509 ~TargetX8632() override {} | 576 ~TargetX8632() override {} |
577 BoolFolding FoldingInfo; | |
510 }; | 578 }; |
511 | 579 |
512 class TargetDataX8632 : public TargetDataLowering { | 580 class TargetDataX8632 : public TargetDataLowering { |
513 TargetDataX8632() = delete; | 581 TargetDataX8632() = delete; |
514 TargetDataX8632(const TargetDataX8632 &) = delete; | 582 TargetDataX8632(const TargetDataX8632 &) = delete; |
515 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; | 583 TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; |
516 | 584 |
517 public: | 585 public: |
518 static TargetDataLowering *create(GlobalContext *Ctx) { | 586 static TargetDataLowering *create(GlobalContext *Ctx) { |
519 return new TargetDataX8632(Ctx); | 587 return new TargetDataX8632(Ctx); |
520 } | 588 } |
521 | 589 |
522 void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final; | 590 void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final; |
523 void lowerConstants() const final; | 591 void lowerConstants() const final; |
524 | 592 |
525 protected: | 593 protected: |
526 explicit TargetDataX8632(GlobalContext *Ctx); | 594 explicit TargetDataX8632(GlobalContext *Ctx); |
527 | 595 |
528 private: | 596 private: |
529 void lowerGlobal(const VariableDeclaration &Var) const; | 597 void lowerGlobal(const VariableDeclaration &Var) const; |
530 ~TargetDataX8632() override {} | 598 ~TargetDataX8632() override {} |
531 template <typename T> static void emitConstantPool(GlobalContext *Ctx); | 599 template <typename T> static void emitConstantPool(GlobalContext *Ctx); |
532 }; | 600 }; |
533 | 601 |
534 } // end of namespace Ice | 602 } // end of namespace Ice |
535 | 603 |
536 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 604 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
OLD | NEW |