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

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: Typo 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
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/llvm2ice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4127 matching lines...) Expand 10 before | Expand all | Expand 10 after
4138 else 4138 else
4139 Reg->setRegNum(RegNum); 4139 Reg->setRegNum(RegNum);
4140 return Reg; 4140 return Reg;
4141 } 4141 }
4142 4142
4143 void TargetX8632::postLower() { 4143 void TargetX8632::postLower() {
4144 if (Ctx->getOptLevel() != Opt_m1) 4144 if (Ctx->getOptLevel() != Opt_m1)
4145 return; 4145 return;
4146 // TODO: Avoid recomputing WhiteList every instruction. 4146 // TODO: Avoid recomputing WhiteList every instruction.
4147 RegSetMask RegInclude = RegSet_All; 4147 RegSetMask RegInclude = RegSet_All;
4148 RegSetMask RegExclude = RegSet_None; 4148 RegSetMask RegExclude = RegSet_FramePointer;
4149 if (hasFramePointer())
4150 RegExclude |= RegSet_FramePointer;
4151 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); 4149 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude);
4152 // Make one pass to black-list pre-colored registers. TODO: If 4150 // Make one pass to black-list pre-colored registers. TODO: If
4153 // there was some prior register allocation pass that made register 4151 // there was some prior register allocation pass that made register
4154 // assignments, those registers need to be black-listed here as 4152 // assignments, those registers need to be black-listed here as
4155 // well. 4153 // well.
4156 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; 4154 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E;
4157 ++I) { 4155 ++I) {
4158 const Inst *Inst = *I; 4156 const Inst *Inst = *I;
4159 if (Inst->isDeleted()) 4157 if (Inst->isDeleted())
4160 continue; 4158 continue;
4161 if (llvm::isa<InstFakeKill>(Inst)) 4159 if (llvm::isa<InstFakeKill>(Inst))
4162 continue; 4160 continue;
4163 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { 4161 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) {
4164 Operand *Src = Inst->getSrc(SrcNum); 4162 Operand *Src = Inst->getSrc(SrcNum);
4165 SizeT NumVars = Src->getNumVars(); 4163 SizeT NumVars = Src->getNumVars();
4166 for (SizeT J = 0; J < NumVars; ++J) { 4164 for (SizeT J = 0; J < NumVars; ++J) {
4167 const Variable *Var = Src->getVar(J); 4165 const Variable *Var = Src->getVar(J);
4168 if (!Var->hasReg()) 4166 if (!Var->hasReg())
4169 continue; 4167 continue;
4170 WhiteList[Var->getRegNum()] = false; 4168 WhiteList[Var->getRegNum()] = false;
4171 } 4169 }
4172 } 4170 }
4173 } 4171 }
4174 // The second pass colors infinite-weight variables. 4172 // The second pass colors infinite-weight variables.
4173
4174 // Indices from which to start looking for the next register in the
4175 // free list.
4176 int32_t PrevFreeRegisterForType[IceType_NUM];
4177 int32_t Uninitialized = -1;
4178 std::fill_n(PrevFreeRegisterForType, IceType_NUM, Uninitialized);
4179 RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
4180
4181 // TODO: The randomized register allocation should choose scratch
4182 // registers before callee save registers.
4183
4175 llvm::SmallBitVector AvailableRegisters = WhiteList; 4184 llvm::SmallBitVector AvailableRegisters = WhiteList;
4176 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; 4185 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E;
4177 ++I) { 4186 ++I) {
4178 const Inst *Inst = *I; 4187 const Inst *Inst = *I;
4179 if (Inst->isDeleted()) 4188 if (Inst->isDeleted())
4180 continue; 4189 continue;
4181 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { 4190 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) {
4182 Operand *Src = Inst->getSrc(SrcNum); 4191 Operand *Src = Inst->getSrc(SrcNum);
4183 SizeT NumVars = Src->getNumVars(); 4192 SizeT NumVars = Src->getNumVars();
4184 for (SizeT J = 0; J < NumVars; ++J) { 4193 for (SizeT J = 0; J < NumVars; ++J) {
4185 Variable *Var = Src->getVar(J); 4194 Variable *Var = Src->getVar(J);
4186 if (Var->hasReg()) 4195 if (Var->hasReg())
4187 continue; 4196 continue;
4188 if (!Var->getWeight().isInf()) 4197 if (!Var->getWeight().isInf())
4189 continue; 4198 continue;
4199 Type Ty = Var->getType();
4200
4190 llvm::SmallBitVector AvailableTypedRegisters = 4201 llvm::SmallBitVector AvailableTypedRegisters =
4191 AvailableRegisters & getRegisterSetForType(Var->getType()); 4202 AvailableRegisters & getRegisterSetForType(Ty);
4203
4192 if (!AvailableTypedRegisters.any()) { 4204 if (!AvailableTypedRegisters.any()) {
4193 // This is a hack in case we run out of physical registers due 4205 // This is a hack in case we run out of physical registers due
4194 // to an excessively long code sequence, as might happen when 4206 // to an excessively long code sequence, as might happen when
4195 // lowering arguments in lowerCall(). 4207 // lowering arguments in lowerCall().
4196 AvailableRegisters = WhiteList; 4208 AvailableRegisters = WhiteList;
4197 AvailableTypedRegisters = 4209 AvailableTypedRegisters =
4198 AvailableRegisters & getRegisterSetForType(Var->getType()); 4210 AvailableRegisters & getRegisterSetForType(Ty);
4199 } 4211 }
4200 assert(AvailableTypedRegisters.any()); 4212 assert(AvailableTypedRegisters.any());
4201 int32_t RegNum = AvailableTypedRegisters.find_first(); 4213
4214 if (PrevFreeRegisterForType[Ty] == Uninitialized &&
4215 RandomizeRegisterAllocation) {
4216 // Start at a random offset in the free list; follow the
4217 // linear order from there.
4218 SizeT StartingRegister = RNG.next(AvailableTypedRegisters.count());
4219 SizeT Index = -1;
4220 for (size_t I = 0; I < StartingRegister; ++I) {
4221 Index = AvailableTypedRegisters.find_next(Index);
4222 }
4223 PrevFreeRegisterForType[Ty] = Index;
4224 }
4225
4226 int32_t PrevRegNum = PrevFreeRegisterForType[Ty];
4227 int32_t RegNum = AvailableTypedRegisters.find_next(PrevRegNum);
4228 if (RegNum == -1) {
4229 // Wraparound
4230 RegNum = AvailableTypedRegisters.find_first();
4231 }
4232 assert(RegNum != -1);
4233
4202 Var->setRegNum(RegNum); 4234 Var->setRegNum(RegNum);
4203 AvailableRegisters[RegNum] = false; 4235 AvailableRegisters[RegNum] = false;
4236 PrevFreeRegisterForType[Ty] = RegNum;
4204 } 4237 }
4205 } 4238 }
4206 } 4239 }
4207 } 4240 }
4241
4242 void TargetX8632::makeRandomRegisterPermutation(
4243 llvm::SmallVectorImpl<int32_t> &Permutation,
4244 const llvm::SmallBitVector &ExcludeRegisters) {
4245 assert(Permutation.size() >= Reg_NUM);
4246 typedef llvm::SmallVector<int32_t, 8> RegisterList;
4247 typedef std::map<unsigned, RegisterList> EquivalenceClassMap;
4248 EquivalenceClassMap EquivalenceClasses;
4249 SizeT NumShuffled = 0, NumPreserved = 0;
4250
4251 // Build up the equivalence classes of registers by looking at the
4252 // register properties as well as whether the registers should be
4253 // explicitly excluded from shuffling.
4254 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \
4255 frameptr, isI8, isInt, isFP) \
4256 if (ExcludeRegisters[val]) { \
4257 /* val stays the same in the resulting permutation. */ \
4258 Permutation[val] = val; \
4259 ++NumPreserved; \
4260 } else { \
4261 union { \
4262 unsigned ClassNum; \
4263 struct { \
4264 unsigned IsScratch : 1; \
4265 unsigned IsPreserved : 1; \
4266 unsigned IsI8 : 1; \
4267 unsigned IsInt : 1; \
4268 unsigned IsFP : 1; \
4269 } Bits; \
4270 } Class = {0}; \
4271 Class.Bits.IsScratch = scratch; \
4272 Class.Bits.IsPreserved = preserved; \
4273 Class.Bits.IsI8 = isI8; \
4274 Class.Bits.IsInt = isInt; \
4275 Class.Bits.IsFP = isFP; \
4276 /* val is assigned to an equivalence class based on its properties. */ \
4277 EquivalenceClasses[Class.ClassNum].push_back(val); \
4278 }
4279 REGX8632_TABLE
4280 #undef X
4281
4282 RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
4283
4284 // Shuffle the resulting equivalence classes.
4285 for (EquivalenceClassMap::const_iterator I = EquivalenceClasses.begin(),
4286 E = EquivalenceClasses.end();
4287 I != E; ++I) {
4288 const RegisterList &List = I->second;
4289 RegisterList Shuffled(List);
4290 std::random_shuffle(Shuffled.begin(), Shuffled.end(), RNG);
4291 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
4292 Permutation[List[SI]] = Shuffled[SI];
4293 ++NumShuffled;
4294 }
4295 }
4296
4297 assert(NumShuffled + NumPreserved == Reg_NUM);
4298
4299 if (Func->getContext()->isVerbose(IceV_Random)) {
4300 Ostream &Str = Func->getContext()->getStrDump();
4301 Str << "Register equivalence classes:\n";
4302 for (EquivalenceClassMap::const_iterator I = EquivalenceClasses.begin(),
4303 E = EquivalenceClasses.end();
4304 I != E; ++I) {
4305 Str << "{";
4306 const RegisterList &List = I->second;
4307 for (SizeT RI = 0, RE = List.size(); RI != RE; ++RI) {
4308 if (RI > 0)
4309 Str << " ";
4310 Str << getRegName(List[RI], IceType_i32);
4311 }
4312 Str << "}\n";
4313 }
4314 }
4315 }
4208 4316
4209 template <> void ConstantInteger::emit(GlobalContext *Ctx) const { 4317 template <> void ConstantInteger::emit(GlobalContext *Ctx) const {
4210 Ostream &Str = Ctx->getStrEmit(); 4318 Ostream &Str = Ctx->getStrEmit();
4211 Str << (int64_t) getValue(); 4319 Str << (int64_t) getValue();
4212 } 4320 }
4213 4321
4214 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { 4322 template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
4215 Ostream &Str = Ctx->getStrEmit(); 4323 Ostream &Str = Ctx->getStrEmit();
4216 // It would be better to prefix with ".L$" instead of "L$", but 4324 // It would be better to prefix with ".L$" instead of "L$", but
4217 // llvm-mc doesn't parse "dword ptr [.L$foo]". 4325 // llvm-mc doesn't parse "dword ptr [.L$foo]".
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4317 Str << "\t.align\t" << Align << "\n"; 4425 Str << "\t.align\t" << Align << "\n";
4318 Str << MangledName << ":\n"; 4426 Str << MangledName << ":\n";
4319 for (SizeT i = 0; i < Size; ++i) { 4427 for (SizeT i = 0; i < Size; ++i) {
4320 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 4428 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
4321 } 4429 }
4322 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4430 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
4323 } 4431 }
4324 } 4432 }
4325 4433
4326 } // end of namespace Ice 4434 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/llvm2ice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698