Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 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 implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 4054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4065 // There aren't any 64-bit integer registers for x86-32. | 4065 // There aren't any 64-bit integer registers for x86-32. |
| 4066 assert(Type != IceType_i64); | 4066 assert(Type != IceType_i64); |
| 4067 Variable *Reg = Func->makeVariable(Type, Context.getNode()); | 4067 Variable *Reg = Func->makeVariable(Type, Context.getNode()); |
| 4068 if (RegNum == Variable::NoRegister) | 4068 if (RegNum == Variable::NoRegister) |
| 4069 Reg->setWeightInfinite(); | 4069 Reg->setWeightInfinite(); |
| 4070 else | 4070 else |
| 4071 Reg->setRegNum(RegNum); | 4071 Reg->setRegNum(RegNum); |
| 4072 return Reg; | 4072 return Reg; |
| 4073 } | 4073 } |
| 4074 | 4074 |
| 4075 extern cl::opt<bool> CLRandomizeRegisterAllocation; | |
|
JF
2014/08/12 05:27:00
This should be imported from the class instead.
wala
2014/08/15 03:37:23
Done.
| |
| 4076 | |
| 4075 void TargetX8632::postLower() { | 4077 void TargetX8632::postLower() { |
| 4076 if (Ctx->getOptLevel() != Opt_m1) | 4078 if (Ctx->getOptLevel() != Opt_m1) |
| 4077 return; | 4079 return; |
| 4078 // TODO: Avoid recomputing WhiteList every instruction. | 4080 // TODO: Avoid recomputing WhiteList every instruction. |
| 4079 RegSetMask RegInclude = RegSet_All; | 4081 RegSetMask RegInclude = RegSet_All; |
| 4080 RegSetMask RegExclude = RegSet_None; | 4082 RegSetMask RegExclude = RegSet_None; |
| 4081 if (hasFramePointer()) | 4083 if (hasFramePointer()) |
| 4082 RegExclude |= RegSet_FramePointer; | 4084 RegExclude |= RegSet_FramePointer; |
| 4083 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); | 4085 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); |
| 4084 // Make one pass to black-list pre-colored registers. TODO: If | 4086 // Make one pass to black-list pre-colored registers. TODO: If |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 4097 SizeT NumVars = Src->getNumVars(); | 4099 SizeT NumVars = Src->getNumVars(); |
| 4098 for (SizeT J = 0; J < NumVars; ++J) { | 4100 for (SizeT J = 0; J < NumVars; ++J) { |
| 4099 const Variable *Var = Src->getVar(J); | 4101 const Variable *Var = Src->getVar(J); |
| 4100 if (!Var->hasReg()) | 4102 if (!Var->hasReg()) |
| 4101 continue; | 4103 continue; |
| 4102 WhiteList[Var->getRegNum()] = false; | 4104 WhiteList[Var->getRegNum()] = false; |
| 4103 } | 4105 } |
| 4104 } | 4106 } |
| 4105 } | 4107 } |
| 4106 // The second pass colors infinite-weight variables. | 4108 // The second pass colors infinite-weight variables. |
| 4109 | |
| 4110 RegisterPermutation Permutation(WhiteList.size()); | |
| 4111 if (CLRandomizeRegisterAllocation) { | |
| 4112 const llvm::SmallBitVector ExcludeRegisters = | |
| 4113 ~WhiteList | getRegisterSet(RegExclude, RegSet_None); | |
| 4114 makeRandomRegisterPermutation(Permutation, ExcludeRegisters); | |
| 4115 } | |
| 4116 | |
| 4107 llvm::SmallBitVector AvailableRegisters = WhiteList; | 4117 llvm::SmallBitVector AvailableRegisters = WhiteList; |
| 4108 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; | 4118 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; |
| 4109 ++I) { | 4119 ++I) { |
| 4110 const Inst *Inst = *I; | 4120 const Inst *Inst = *I; |
| 4111 if (Inst->isDeleted()) | 4121 if (Inst->isDeleted()) |
| 4112 continue; | 4122 continue; |
| 4113 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { | 4123 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { |
| 4114 Operand *Src = Inst->getSrc(SrcNum); | 4124 Operand *Src = Inst->getSrc(SrcNum); |
| 4115 SizeT NumVars = Src->getNumVars(); | 4125 SizeT NumVars = Src->getNumVars(); |
| 4116 for (SizeT J = 0; J < NumVars; ++J) { | 4126 for (SizeT J = 0; J < NumVars; ++J) { |
| 4117 Variable *Var = Src->getVar(J); | 4127 Variable *Var = Src->getVar(J); |
| 4118 if (Var->hasReg()) | 4128 if (Var->hasReg()) |
| 4119 continue; | 4129 continue; |
| 4120 if (!Var->getWeight().isInf()) | 4130 if (!Var->getWeight().isInf()) |
| 4121 continue; | 4131 continue; |
| 4122 llvm::SmallBitVector AvailableTypedRegisters = | 4132 llvm::SmallBitVector AvailableTypedRegisters = |
| 4123 AvailableRegisters & getRegisterSetForType(Var->getType()); | 4133 AvailableRegisters & getRegisterSetForType(Var->getType()); |
| 4124 if (!AvailableTypedRegisters.any()) { | 4134 if (!AvailableTypedRegisters.any()) { |
| 4125 // This is a hack in case we run out of physical registers due | 4135 // This is a hack in case we run out of physical registers due |
| 4126 // to an excessively long code sequence, as might happen when | 4136 // to an excessively long code sequence, as might happen when |
| 4127 // lowering arguments in lowerCall(). | 4137 // lowering arguments in lowerCall(). |
| 4128 AvailableRegisters = WhiteList; | 4138 AvailableRegisters = WhiteList; |
| 4129 AvailableTypedRegisters = | 4139 AvailableTypedRegisters = |
| 4130 AvailableRegisters & getRegisterSetForType(Var->getType()); | 4140 AvailableRegisters & getRegisterSetForType(Var->getType()); |
| 4131 } | 4141 } |
| 4132 assert(AvailableTypedRegisters.any()); | 4142 assert(AvailableTypedRegisters.any()); |
| 4133 int32_t RegNum = AvailableTypedRegisters.find_first(); | 4143 int32_t RegNum = AvailableTypedRegisters.find_first(); |
| 4134 Var->setRegNum(RegNum); | 4144 if (CLRandomizeRegisterAllocation) { |
| 4145 Var->setRegNum(Permutation[RegNum]); | |
| 4146 } else { | |
| 4147 Var->setRegNum(RegNum); | |
| 4148 } | |
| 4135 AvailableRegisters[RegNum] = false; | 4149 AvailableRegisters[RegNum] = false; |
| 4136 } | 4150 } |
| 4137 } | 4151 } |
| 4138 } | 4152 } |
| 4139 } | 4153 } |
| 4140 | 4154 |
| 4155 void TargetX8632::makeRandomRegisterPermutation( | |
|
Jim Stichnoth
2014/08/14 01:10:29
I know this has already been discussed offline, bu
wala
2014/08/15 03:37:23
Done.
| |
| 4156 RegisterPermutation &Permutation, | |
| 4157 const llvm::SmallBitVector &ExcludeRegisters) { | |
| 4158 assert(Permutation.size() == Reg_NUM); | |
| 4159 typedef llvm::SmallVector<int32_t, 8> RegisterList; | |
| 4160 typedef std::map<uint8_t, RegisterList> EquivalenceClassMap; | |
| 4161 EquivalenceClassMap EquivalenceClasses; | |
| 4162 SizeT NumShuffled = 0, NumPreserved = 0; | |
| 4163 | |
| 4164 // Build up the equivalence classes of registers by looking at the | |
| 4165 // register properties as well as whether the registers should be | |
| 4166 // explicitly excluded from shuffling. | |
| 4167 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ | |
| 4168 frameptr, isI8, isInt, isFP) \ | |
| 4169 if (ExcludeRegisters[val]) { \ | |
| 4170 /* val stays the same in the resulting permutation. */ \ | |
| 4171 Permutation[val] = val; \ | |
| 4172 ++NumPreserved; \ | |
| 4173 } else { \ | |
| 4174 union { \ | |
| 4175 uint8_t ClassNum; \ | |
| 4176 struct { \ | |
| 4177 uint8_t IsScratch:1; \ | |
|
Jim Stichnoth
2014/08/14 01:10:29
For bitfields I think you can just use unsigned.
wala
2014/08/15 03:37:23
Done.
| |
| 4178 uint8_t IsPreserved:1; \ | |
| 4179 uint8_t IsI8:1; \ | |
| 4180 uint8_t IsInt:1; \ | |
| 4181 uint8_t IsFP:1; \ | |
| 4182 } Bits; \ | |
| 4183 } Class = {0}; \ | |
| 4184 Class.Bits.IsScratch = scratch; \ | |
| 4185 Class.Bits.IsPreserved = preserved; \ | |
| 4186 Class.Bits.IsI8 = isI8; \ | |
| 4187 Class.Bits.IsInt = isInt; \ | |
| 4188 Class.Bits.IsFP = isFP; \ | |
| 4189 /* val is assigned to an equivalence class based on its properties. */ \ | |
| 4190 EquivalenceClasses[Class.ClassNum].push_back(val); \ | |
| 4191 } | |
| 4192 REGX8632_TABLE | |
| 4193 #undef X | |
| 4194 | |
| 4195 RandomNumberGeneratorWrapper RNG = Ctx->getRNG(); | |
| 4196 | |
| 4197 // Shuffle the resulting equivalence classes. | |
| 4198 for (EquivalenceClassMap::const_iterator I = EquivalenceClasses.begin(), | |
| 4199 E = EquivalenceClasses.end(); I != E; ++I) { | |
| 4200 const RegisterList &List = I->second; | |
| 4201 RegisterList Shuffled(List); | |
| 4202 std::random_shuffle(Shuffled.begin(), Shuffled.end(), RNG); | |
| 4203 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | |
| 4204 Permutation[List[SI]] = Shuffled[SI]; | |
| 4205 ++NumShuffled; | |
| 4206 } | |
| 4207 } | |
| 4208 | |
| 4209 assert(NumShuffled + NumPreserved == Reg_NUM); | |
| 4210 | |
| 4211 if (Func->getContext()->isVerbose(IceV_Random)) { | |
| 4212 Ostream &Str = Func->getContext()->getStrDump(); | |
| 4213 Str << "Register equivalence classes:\n"; | |
| 4214 for (EquivalenceClassMap::const_iterator I = EquivalenceClasses.begin(), | |
| 4215 E = EquivalenceClasses.end(); I != E; ++I) { | |
| 4216 Str << "{"; | |
| 4217 const RegisterList &List = I->second; | |
| 4218 for (SizeT RI = 0, RE = List.size(); RI != RE; ++RI) { | |
| 4219 if (RI > 0) | |
| 4220 Str << " "; | |
| 4221 Str << getRegName(List[RI], IceType_i32); | |
| 4222 } | |
| 4223 Str << "}\n"; | |
| 4224 } | |
| 4225 } | |
| 4226 } | |
| 4227 | |
| 4141 template <> void ConstantInteger::emit(GlobalContext *Ctx) const { | 4228 template <> void ConstantInteger::emit(GlobalContext *Ctx) const { |
| 4142 Ostream &Str = Ctx->getStrEmit(); | 4229 Ostream &Str = Ctx->getStrEmit(); |
| 4143 Str << (int64_t) getValue(); | 4230 Str << (int64_t) getValue(); |
| 4144 } | 4231 } |
| 4145 | 4232 |
| 4146 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { | 4233 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { |
| 4147 Ostream &Str = Ctx->getStrEmit(); | 4234 Ostream &Str = Ctx->getStrEmit(); |
| 4148 // It would be better to prefix with ".L$" instead of "L$", but | 4235 // It would be better to prefix with ".L$" instead of "L$", but |
| 4149 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 4236 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
| 4150 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 4237 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4249 for (SizeT i = 0; i < Size; ++i) { | 4336 for (SizeT i = 0; i < Size; ++i) { |
| 4250 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4337 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4251 } | 4338 } |
| 4252 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4339 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4253 } | 4340 } |
| 4254 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 4341 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
| 4255 << "\n"; | 4342 << "\n"; |
| 4256 } | 4343 } |
| 4257 | 4344 |
| 4258 } // end of namespace Ice | 4345 } // end of namespace Ice |
| OLD | NEW |