Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(574)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 456033003: Subzero: Randomize register assignment. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Remove redundancies. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698