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 |