| 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 |
| 11 /// \brief Implements the skeleton of the TargetLowering class. | 11 /// \brief Implements the skeleton of the TargetLowering class. |
| 12 /// | 12 /// |
| 13 /// Specifically this invokes the appropriate lowering method for a given | 13 /// Specifically this invokes the appropriate lowering method for a given |
| 14 /// instruction kind and driving global register allocation. It also implements | 14 /// instruction kind and driving global register allocation. It also implements |
| 15 /// the non-deleted instruction iteration in LoweringContext. | 15 /// the non-deleted instruction iteration in LoweringContext. |
| 16 /// | 16 /// |
| 17 //===----------------------------------------------------------------------===// | 17 //===----------------------------------------------------------------------===// |
| 18 | 18 |
| 19 #include "IceTargetLowering.h" | 19 #include "IceTargetLowering.h" |
| 20 | 20 |
| 21 #include "IceBitVector.h" | 21 #include "IceBitVector.h" |
| 22 #include "IceCfg.h" // setError() | 22 #include "IceCfg.h" // setError() |
| 23 #include "IceCfgNode.h" | 23 #include "IceCfgNode.h" |
| 24 #include "IceGlobalContext.h" | 24 #include "IceGlobalContext.h" |
| 25 #include "IceGlobalInits.h" | 25 #include "IceGlobalInits.h" |
| 26 #include "IceInstVarIter.h" | 26 #include "IceInstVarIter.h" |
| 27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
| 28 #include "IceRegAlloc.h" | 28 #include "IceRegAlloc.h" |
| 29 | 29 |
| 30 #include <string> |
| 31 #include <vector> |
| 32 |
| 30 #define TARGET_LOWERING_CLASS_FOR(t) Target_##t | 33 #define TARGET_LOWERING_CLASS_FOR(t) Target_##t |
| 31 | 34 |
| 32 // We prevent target-specific implementation details from leaking outside their | 35 // We prevent target-specific implementation details from leaking outside their |
| 33 // implementations by forbidding #include of target-specific header files | 36 // implementations by forbidding #include of target-specific header files |
| 34 // anywhere outside their own files. To create target-specific objects | 37 // anywhere outside their own files. To create target-specific objects |
| 35 // (TargetLowering, TargetDataLowering, and TargetHeaderLowering) we use the | 38 // (TargetLowering, TargetDataLowering, and TargetHeaderLowering) we use the |
| 36 // following named constructors. For reference, each target Foo needs to | 39 // following named constructors. For reference, each target Foo needs to |
| 37 // implement the following named constructors and initializer: | 40 // implement the following named constructors and initializer: |
| 38 // | 41 // |
| 39 // namespace Foo { | 42 // namespace Foo { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 SmallBitVector(NumRegs)); | 175 SmallBitVector(NumRegs)); |
| 173 std::vector<SmallBitVector> ExcludeSet(TypeToRegisterSetSize, | 176 std::vector<SmallBitVector> ExcludeSet(TypeToRegisterSetSize, |
| 174 SmallBitVector(NumRegs)); | 177 SmallBitVector(NumRegs)); |
| 175 | 178 |
| 176 std::unordered_map<IceString, RegNumT> RegNameToIndex; | 179 std::unordered_map<IceString, RegNumT> RegNameToIndex; |
| 177 for (int32_t RegIndex = 0; RegIndex < NumRegs; ++RegIndex) { | 180 for (int32_t RegIndex = 0; RegIndex < NumRegs; ++RegIndex) { |
| 178 const auto RegNum = RegNumT::fromInt(RegIndex); | 181 const auto RegNum = RegNumT::fromInt(RegIndex); |
| 179 RegNameToIndex[getRegName(RegNum)] = RegNum; | 182 RegNameToIndex[getRegName(RegNum)] = RegNum; |
| 180 } | 183 } |
| 181 | 184 |
| 182 ClFlags::StringVector BadRegNames; | 185 std::vector<std::string> BadRegNames; |
| 183 | 186 |
| 184 // The processRegList function iterates across the RegNames vector. Each | 187 // The processRegList function iterates across the RegNames vector. Each |
| 185 // entry in the vector is a string of the form "<reg>" or "<class>:<reg>". | 188 // entry in the vector is a string of the form "<reg>" or "<class>:<reg>". |
| 186 // The register class and register number are computed, and the corresponding | 189 // The register class and register number are computed, and the corresponding |
| 187 // bit is set in RegSet[][]. If "<class>:" is missing, then the bit is set | 190 // bit is set in RegSet[][]. If "<class>:" is missing, then the bit is set |
| 188 // for all classes. | 191 // for all classes. |
| 189 auto processRegList = [&](const ClFlags::StringVector &RegNames, | 192 auto processRegList = [&](const std::vector<std::string> &RegNames, |
| 190 std::vector<SmallBitVector> &RegSet) { | 193 std::vector<SmallBitVector> &RegSet) { |
| 191 for (const IceString &RegClassAndName : RegNames) { | 194 for (const IceString &RegClassAndName : RegNames) { |
| 192 IceString RClass; | 195 IceString RClass; |
| 193 IceString RName; | 196 IceString RName; |
| 194 splitToClassAndName(RegClassAndName, &RClass, &RName); | 197 splitToClassAndName(RegClassAndName, &RClass, &RName); |
| 195 if (!RegNameToIndex.count(RName)) { | 198 if (!RegNameToIndex.count(RName)) { |
| 196 BadRegNames.push_back(RName); | 199 BadRegNames.push_back(RName); |
| 197 continue; | 200 continue; |
| 198 } | 201 } |
| 199 const int32_t RegIndex = RegNameToIndex.at(RName); | 202 const int32_t RegIndex = RegNameToIndex.at(RName); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 void TargetLowering::regAlloc(RegAllocKind Kind) { | 470 void TargetLowering::regAlloc(RegAllocKind Kind) { |
| 468 TimerMarker T(TimerStack::TT_regAlloc, Func); | 471 TimerMarker T(TimerStack::TT_regAlloc, Func); |
| 469 LinearScan LinearScan(Func); | 472 LinearScan LinearScan(Func); |
| 470 RegSetMask RegInclude = RegSet_None; | 473 RegSetMask RegInclude = RegSet_None; |
| 471 RegSetMask RegExclude = RegSet_None; | 474 RegSetMask RegExclude = RegSet_None; |
| 472 RegInclude |= RegSet_CallerSave; | 475 RegInclude |= RegSet_CallerSave; |
| 473 RegInclude |= RegSet_CalleeSave; | 476 RegInclude |= RegSet_CalleeSave; |
| 474 if (hasFramePointer()) | 477 if (hasFramePointer()) |
| 475 RegExclude |= RegSet_FramePointer; | 478 RegExclude |= RegSet_FramePointer; |
| 476 SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude); | 479 SmallBitVector RegMask = getRegisterSet(RegInclude, RegExclude); |
| 477 bool Repeat = (Kind == RAK_Global && Ctx->getFlags().shouldRepeatRegAlloc()); | 480 bool Repeat = (Kind == RAK_Global && Ctx->getFlags().getRepeatRegAlloc()); |
| 478 do { | 481 do { |
| 479 LinearScan.init(Kind); | 482 LinearScan.init(Kind); |
| 480 LinearScan.scan(RegMask, Ctx->getFlags().shouldRandomizeRegAlloc()); | 483 LinearScan.scan(RegMask, Ctx->getFlags().getRandomizeRegisterAllocation()); |
| 481 if (!LinearScan.hasEvictions()) | 484 if (!LinearScan.hasEvictions()) |
| 482 Repeat = false; | 485 Repeat = false; |
| 483 Kind = RAK_SecondChance; | 486 Kind = RAK_SecondChance; |
| 484 } while (Repeat); | 487 } while (Repeat); |
| 485 // TODO(stichnot): Run the register allocator one more time to do stack slot | 488 // TODO(stichnot): Run the register allocator one more time to do stack slot |
| 486 // coalescing. The idea would be to initialize the Unhandled list with the | 489 // coalescing. The idea would be to initialize the Unhandled list with the |
| 487 // set of Variables that have no register and a non-empty live range, and | 490 // set of Variables that have no register and a non-empty live range, and |
| 488 // model an infinite number of registers. Maybe use the register aliasing | 491 // model an infinite number of registers. Maybe use the register aliasing |
| 489 // mechanism to get better packing of narrower slots. | 492 // mechanism to get better packing of narrower slots. |
| 490 } | 493 } |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 case TARGET_LOWERING_CLASS_FOR(X): \ | 884 case TARGET_LOWERING_CLASS_FOR(X): \ |
| 882 return ::X::createTargetHeaderLowering(Ctx); | 885 return ::X::createTargetHeaderLowering(Ctx); |
| 883 #include "SZTargets.def" | 886 #include "SZTargets.def" |
| 884 #undef SUBZERO_TARGET | 887 #undef SUBZERO_TARGET |
| 885 } | 888 } |
| 886 } | 889 } |
| 887 | 890 |
| 888 TargetHeaderLowering::~TargetHeaderLowering() = default; | 891 TargetHeaderLowering::~TargetHeaderLowering() = default; |
| 889 | 892 |
| 890 } // end of namespace Ice | 893 } // end of namespace Ice |
| OLD | NEW |