Chromium Code Reviews| 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 /// \file | 10 /// \file |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 // (TargetLowering, TargetDataLowering, and TargetHeaderLowering) we use the | 32 // (TargetLowering, TargetDataLowering, and TargetHeaderLowering) we use the |
| 33 // following named constructors. For reference, each target Foo needs to | 33 // following named constructors. For reference, each target Foo needs to |
| 34 // implement the following named constructors and initializer: | 34 // implement the following named constructors and initializer: |
| 35 // | 35 // |
| 36 // namespace Foo { | 36 // namespace Foo { |
| 37 // unique_ptr<Ice::TargetLowering> createTargetLowering(Ice::Cfg *); | 37 // unique_ptr<Ice::TargetLowering> createTargetLowering(Ice::Cfg *); |
| 38 // unique_ptr<Ice::TargetDataLowering> | 38 // unique_ptr<Ice::TargetDataLowering> |
| 39 // createTargetDataLowering(Ice::GlobalContext*); | 39 // createTargetDataLowering(Ice::GlobalContext*); |
| 40 // unique_ptr<Ice::TargetHeaderLowering> | 40 // unique_ptr<Ice::TargetHeaderLowering> |
| 41 // createTargetHeaderLowering(Ice::GlobalContext *); | 41 // createTargetHeaderLowering(Ice::GlobalContext *); |
| 42 // void staticInit(const ::Ice::ClFlags &Flags); | 42 // void staticInit(::Ice::GlobalContext *); |
| 43 // } | 43 // } |
| 44 #define SUBZERO_TARGET(X) \ | 44 #define SUBZERO_TARGET(X) \ |
| 45 namespace X { \ | 45 namespace X { \ |
| 46 std::unique_ptr<::Ice::TargetLowering> \ | 46 std::unique_ptr<::Ice::TargetLowering> \ |
| 47 createTargetLowering(::Ice::Cfg *Func); \ | 47 createTargetLowering(::Ice::Cfg *Func); \ |
| 48 std::unique_ptr<::Ice::TargetDataLowering> \ | 48 std::unique_ptr<::Ice::TargetDataLowering> \ |
| 49 createTargetDataLowering(::Ice::GlobalContext *Ctx); \ | 49 createTargetDataLowering(::Ice::GlobalContext *Ctx); \ |
| 50 std::unique_ptr<::Ice::TargetHeaderLowering> \ | 50 std::unique_ptr<::Ice::TargetHeaderLowering> \ |
| 51 createTargetHeaderLowering(::Ice::GlobalContext *Ctx); \ | 51 createTargetHeaderLowering(::Ice::GlobalContext *Ctx); \ |
| 52 void staticInit(const ::Ice::ClFlags &Flags); \ | 52 void staticInit(::Ice::GlobalContext *Ctx); \ |
| 53 } // end of namespace X | 53 } // end of namespace X |
| 54 #include "llvm/Config/SZTargets.def" | 54 #include "llvm/Config/SZTargets.def" |
| 55 #undef SUBZERO_TARGET | 55 #undef SUBZERO_TARGET |
| 56 | 56 |
| 57 namespace Ice { | 57 namespace Ice { |
| 58 void LoweringContext::init(CfgNode *N) { | 58 void LoweringContext::init(CfgNode *N) { |
| 59 Node = N; | 59 Node = N; |
| 60 End = getNode()->getInsts().end(); | 60 End = getNode()->getInsts().end(); |
| 61 rewind(); | 61 rewind(); |
| 62 advanceForward(Next); | 62 advanceForward(Next); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 LastSrc = llvm::cast<Variable>(Instr->getSrc(0)); | 109 LastSrc = llvm::cast<Variable>(Instr->getSrc(0)); |
| 110 } | 110 } |
| 111 | 111 |
| 112 Variable *LoweringContext::availabilityGet(Operand *Src) const { | 112 Variable *LoweringContext::availabilityGet(Operand *Src) const { |
| 113 assert(Src); | 113 assert(Src); |
| 114 if (Src == LastDest) | 114 if (Src == LastDest) |
| 115 return LastSrc; | 115 return LastSrc; |
| 116 return nullptr; | 116 return nullptr; |
| 117 } | 117 } |
| 118 | 118 |
| 119 namespace { | |
| 120 | |
| 121 void indent(Ostream &Str, SizeT LineIndent) { | |
| 122 for (SizeT i = 0; i < LineIndent; ++i) | |
| 123 Str << ' '; | |
| 124 } | |
| 125 | |
| 126 void printRegisterSet(Ostream &Str, const llvm::SmallBitVector &Bitset, | |
| 127 std::function<IceString(int32_t)> getRegName, | |
| 128 SizeT LineIndent) { | |
| 129 constexpr SizeT RegistersPerLine = 16; | |
| 130 SizeT Count = 0; | |
| 131 for (SizeT i = 0; i < Bitset.size(); ++i) { | |
|
Jim Stichnoth
2016/01/14 22:04:19
The usual pattern for iterating over the set bits
Karl
2016/01/14 23:54:51
Done.
| |
| 132 if (!Bitset[i]) | |
| 133 continue; | |
| 134 if (Count == 0) { | |
| 135 indent(Str, LineIndent); | |
|
Jim Stichnoth
2016/01/14 22:04:19
I think you can remove the indent function, and ju
Karl
2016/01/14 23:54:51
Done.
| |
| 136 } else if (Count % RegistersPerLine == 0) { | |
| 137 Str << "\n"; | |
| 138 indent(Str, LineIndent); | |
| 139 } else { | |
| 140 Str << ", "; | |
|
Jim Stichnoth
2016/01/14 22:04:19
I would just print a space and drop the comma. It
Karl
2016/01/14 23:54:51
Done.
| |
| 141 } | |
| 142 ++Count; | |
| 143 Str << getRegName(i); | |
| 144 } | |
| 145 if (Count) | |
| 146 Str << "\n"; | |
| 147 } | |
| 148 | |
| 149 } // end of anonymous namespace | |
| 150 | |
| 151 void TargetLowering::filterTypeToRegisterSet( | |
| 152 GlobalContext *Ctx, int32_t NumRegs, | |
| 153 llvm::SmallBitVector *TypeToRegisterSet, SizeT TypeToRegisterSetSize, | |
| 154 std::function<IceString(int32_t)> getRegName) { | |
| 155 llvm::SmallBitVector ExcludeBitSet(NumRegs); | |
| 156 std::vector<llvm::SmallBitVector> UseSet(TypeToRegisterSetSize, | |
| 157 ExcludeBitSet); | |
| 158 ExcludeBitSet.flip(); | |
| 159 | |
| 160 // Translate use/exclude name sets to corresponding bitsets. | |
| 161 const std::unordered_set<std::string> &UseName = | |
|
John
2016/01/14 21:12:49
really great candidate for auto:
const auto &UseN
Karl
2016/01/14 22:00:52
Did change to IceString.
Jim Stichnoth
2016/01/14 22:04:19
IceString
| |
| 162 Ctx->getFlags().getUseRestrictedRegisters(); | |
| 163 const std::unordered_set<std::string> &ExcludeName = | |
| 164 Ctx->getFlags().getExcludedRegisters(); | |
| 165 for (int32_t RegIndex = 0; RegIndex < NumRegs; ++RegIndex) { | |
|
John
2016/01/14 21:12:48
This loop iterates over all registers, but it only
Karl
2016/01/14 22:00:53
Acknowledged.
| |
| 166 IceString RegName(getRegName(RegIndex)); | |
|
John
2016/01/14 21:12:48
I usually prefer assignments when initializing str
Karl
2016/01/14 22:00:52
I thought the form "clsname foo = bar;" Creates fo
| |
| 167 if (UseName.count(RegName)) { | |
|
Jim Stichnoth
2016/01/14 22:04:19
I realize UseName is const, but it would be extra
Karl
2016/01/14 23:54:51
Done.
| |
| 168 for (SizeT TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; | |
| 169 ++TypeIndex) { | |
| 170 UseSet[TypeIndex][RegIndex] = TypeToRegisterSet[TypeIndex][RegIndex]; | |
| 171 } | |
| 172 } | |
| 173 if (ExcludeName.count(RegName)) | |
| 174 ExcludeBitSet[RegIndex] = false; | |
| 175 } | |
| 176 | |
| 177 // Apply filters. | |
| 178 for (SizeT TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) { | |
| 179 llvm::SmallBitVector &TypeBitSet = TypeToRegisterSet[TypeIndex]; | |
|
John
2016/01/14 21:12:48
can you use a * here?
(yes, I know I am the only
Karl
2016/01/14 22:00:52
Done.
| |
| 180 llvm::SmallBitVector &UseBitSet = UseSet[TypeIndex]; | |
| 181 if (UseBitSet.any()) | |
| 182 TypeBitSet = UseBitSet; | |
| 183 TypeBitSet &= ExcludeBitSet; | |
| 184 } | |
| 185 | |
| 186 // Display filtered register sets, if requested. | |
| 187 if (BuildDefs::dump() && NumRegs && | |
| 188 (Ctx->getFlags().getVerbose() & IceV_AvailableRegs)) { | |
| 189 Ostream &Str = Ctx->getStrEmit(); | |
|
Jim Stichnoth
2016/01/14 22:04:19
getStrDump
Karl
2016/01/14 23:54:51
Done.
| |
| 190 constexpr const char *LineIndent = " "; | |
|
John
2016/01/14 21:12:49
please use
constexpr char LineIndent = " ";
inst
Karl
2016/01/14 22:00:52
If I remove the const, the type is "char *const" (
| |
| 191 SizeT RegSetIndent = 2 * strlen(LineIndent); | |
|
John
2016/01/14 21:12:48
and then using llvm::array_lengthof() should let y
Karl
2016/01/14 22:00:52
Able to change using 'constexpr const char LineInd
Jim Stichnoth
2016/01/14 22:04:19
Can this be constexpr? :)
(at least const, surely
Karl
2016/01/14 23:54:51
Done.
| |
| 192 Str << "Registers available for register allocation:\n"; | |
| 193 for (SizeT TypeIndex = 0; TypeIndex < TypeToRegisterSetSize; ++TypeIndex) { | |
| 194 Str << LineIndent; | |
| 195 if (TypeIndex < IceType_NUM) { | |
| 196 Str << typeString(static_cast<Type>(TypeIndex)); | |
| 197 } else { | |
| 198 Str << "other[" << TypeIndex << "]"; | |
| 199 } | |
| 200 Str << ":\n"; | |
| 201 printRegisterSet(Str, TypeToRegisterSet[TypeIndex], getRegName, | |
| 202 RegSetIndent); | |
| 203 } | |
| 204 Str << "\n"; | |
| 205 } | |
| 206 } | |
| 207 | |
| 119 std::unique_ptr<TargetLowering> | 208 std::unique_ptr<TargetLowering> |
| 120 TargetLowering::createLowering(TargetArch Target, Cfg *Func) { | 209 TargetLowering::createLowering(TargetArch Target, Cfg *Func) { |
| 121 switch (Target) { | 210 switch (Target) { |
| 122 default: | 211 default: |
| 123 llvm::report_fatal_error("Unsupported target"); | 212 llvm::report_fatal_error("Unsupported target"); |
| 124 #define SUBZERO_TARGET(X) \ | 213 #define SUBZERO_TARGET(X) \ |
| 125 case Target_##X: \ | 214 case Target_##X: \ |
| 126 return ::X::createTargetLowering(Func); | 215 return ::X::createTargetLowering(Func); |
| 127 #include "llvm/Config/SZTargets.def" | 216 #include "llvm/Config/SZTargets.def" |
| 128 #undef SUBZERO_TARGET | 217 #undef SUBZERO_TARGET |
| 129 } | 218 } |
| 130 } | 219 } |
| 131 | 220 |
| 132 void TargetLowering::staticInit(const ClFlags &Flags) { | 221 void TargetLowering::staticInit(GlobalContext *Ctx) { |
| 133 const TargetArch Target = Flags.getTargetArch(); | 222 const TargetArch Target = Ctx->getFlags().getTargetArch(); |
| 134 // Call the specified target's static initializer. | 223 // Call the specified target's static initializer. |
| 135 switch (Target) { | 224 switch (Target) { |
| 136 default: | 225 default: |
| 137 llvm::report_fatal_error("Unsupported target"); | 226 llvm::report_fatal_error("Unsupported target"); |
| 138 #define SUBZERO_TARGET(X) \ | 227 #define SUBZERO_TARGET(X) \ |
| 139 case Target_##X: { \ | 228 case Target_##X: { \ |
| 140 static bool InitGuard##X = false; \ | 229 static bool InitGuard##X = false; \ |
| 141 if (InitGuard##X) { \ | 230 if (InitGuard##X) { \ |
| 142 return; \ | 231 return; \ |
| 143 } \ | 232 } \ |
| 144 InitGuard##X = true; \ | 233 InitGuard##X = true; \ |
| 145 ::X::staticInit(Flags); \ | 234 ::X::staticInit(Ctx); \ |
| 146 } break; | 235 } break; |
| 147 #include "llvm/Config/SZTargets.def" | 236 #include "llvm/Config/SZTargets.def" |
| 148 #undef SUBZERO_TARGET | 237 #undef SUBZERO_TARGET |
| 149 } | 238 } |
| 150 } | 239 } |
| 151 | 240 |
| 152 TargetLowering::TargetLowering(Cfg *Func) | 241 TargetLowering::TargetLowering(Cfg *Func) |
| 153 : Func(Func), Ctx(Func->getContext()), Context() {} | 242 : Func(Func), Ctx(Func->getContext()), Context() {} |
| 154 | 243 |
| 155 void TargetLowering::genTargetHelperCalls() { | 244 void TargetLowering::genTargetHelperCalls() { |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 case Target_##X: \ | 771 case Target_##X: \ |
| 683 return ::X::createTargetHeaderLowering(Ctx); | 772 return ::X::createTargetHeaderLowering(Ctx); |
| 684 #include "llvm/Config/SZTargets.def" | 773 #include "llvm/Config/SZTargets.def" |
| 685 #undef SUBZERO_TARGET | 774 #undef SUBZERO_TARGET |
| 686 } | 775 } |
| 687 } | 776 } |
| 688 | 777 |
| 689 TargetHeaderLowering::~TargetHeaderLowering() = default; | 778 TargetHeaderLowering::~TargetHeaderLowering() = default; |
| 690 | 779 |
| 691 } // end of namespace Ice | 780 } // end of namespace Ice |
| OLD | NEW |