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 3851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3862 Constant *OffsetOp = Ctx->getConstantInt32(Offset); | 3862 Constant *OffsetOp = Ctx->getConstantInt32(Offset); |
3863 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, | 3863 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, |
3864 Shift, SegmentReg); | 3864 Shift, SegmentReg); |
3865 Context.insert(InstLoad::create(Func, Dest, Addr)); | 3865 Context.insert(InstLoad::create(Func, Dest, Addr)); |
3866 } | 3866 } |
3867 } | 3867 } |
3868 | 3868 |
3869 void TargetX8632::randomlyInsertNop(float Probability) { | 3869 void TargetX8632::randomlyInsertNop(float Probability) { |
3870 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); | 3870 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
3871 if (RNG.getTrueWithProbability(Probability)) { | 3871 if (RNG.getTrueWithProbability(Probability)) { |
3872 _nop(RNG.next(X86_NUM_NOP_VARIANTS)); | 3872 _nop(RNG(X86_NUM_NOP_VARIANTS)); |
3873 } | 3873 } |
3874 } | 3874 } |
3875 | 3875 |
3876 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { | 3876 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { |
3877 Func->setError("Phi found in regular instruction list"); | 3877 Func->setError("Phi found in regular instruction list"); |
3878 } | 3878 } |
3879 | 3879 |
3880 void TargetX8632::lowerRet(const InstRet *Inst) { | 3880 void TargetX8632::lowerRet(const InstRet *Inst) { |
3881 Variable *Reg = NULL; | 3881 Variable *Reg = NULL; |
3882 if (Inst->hasRetValue()) { | 3882 if (Inst->hasRetValue()) { |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4523 if (Variable *Dest = Inst->getDest()) { | 4523 if (Variable *Dest = Inst->getDest()) { |
4524 // TODO(stichnot): We may need to consider all source | 4524 // TODO(stichnot): We may need to consider all source |
4525 // operands, not just the first one, if using 3-address | 4525 // operands, not just the first one, if using 3-address |
4526 // instructions. | 4526 // instructions. |
4527 if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) | 4527 if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) |
4528 Inst->setDestNonKillable(); | 4528 Inst->setDestNonKillable(); |
4529 } | 4529 } |
4530 } | 4530 } |
4531 } | 4531 } |
4532 | 4532 |
| 4533 void TargetX8632::makeRandomRegisterPermutation( |
| 4534 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 4535 const llvm::SmallBitVector &ExcludeRegisters) const { |
| 4536 // TODO(stichnot): Declaring Permutation this way loses type/size |
| 4537 // information. Fix this in conjunction with the caller-side TODO. |
| 4538 assert(Permutation.size() >= RegX8632::Reg_NUM); |
| 4539 // Expected upper bound on the number of registers in a single |
| 4540 // equivalence class. For x86-32, this would comprise the 8 XMM |
| 4541 // registers. This is for performance, not correctness. |
| 4542 static const unsigned MaxEquivalenceClassSize = 8; |
| 4543 typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList; |
| 4544 typedef std::map<uint32_t, RegisterList> EquivalenceClassMap; |
| 4545 EquivalenceClassMap EquivalenceClasses; |
| 4546 SizeT NumShuffled = 0, NumPreserved = 0; |
| 4547 |
| 4548 // Build up the equivalence classes of registers by looking at the |
| 4549 // register properties as well as whether the registers should be |
| 4550 // explicitly excluded from shuffling. |
| 4551 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 4552 frameptr, isI8, isInt, isFP) \ |
| 4553 if (ExcludeRegisters[RegX8632::val]) { \ |
| 4554 /* val stays the same in the resulting permutation. */ \ |
| 4555 Permutation[RegX8632::val] = RegX8632::val; \ |
| 4556 ++NumPreserved; \ |
| 4557 } else { \ |
| 4558 const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ |
| 4559 (isInt << 3) | (isFP << 4); \ |
| 4560 /* val is assigned to an equivalence class based on its properties. */ \ |
| 4561 EquivalenceClasses[Index].push_back(RegX8632::val); \ |
| 4562 } |
| 4563 REGX8632_TABLE |
| 4564 #undef X |
| 4565 |
| 4566 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
| 4567 |
| 4568 // Shuffle the resulting equivalence classes. |
| 4569 for (auto I : EquivalenceClasses) { |
| 4570 const RegisterList &List = I.second; |
| 4571 RegisterList Shuffled(List); |
| 4572 std::random_shuffle(Shuffled.begin(), Shuffled.end(), RNG); |
| 4573 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
| 4574 Permutation[List[SI]] = Shuffled[SI]; |
| 4575 ++NumShuffled; |
| 4576 } |
| 4577 } |
| 4578 |
| 4579 assert(NumShuffled + NumPreserved == RegX8632::Reg_NUM); |
| 4580 |
| 4581 if (Func->getContext()->isVerbose(IceV_Random)) { |
| 4582 Ostream &Str = Func->getContext()->getStrDump(); |
| 4583 Str << "Register equivalence classes:\n"; |
| 4584 for (auto I : EquivalenceClasses) { |
| 4585 Str << "{"; |
| 4586 const RegisterList &List = I.second; |
| 4587 bool First = true; |
| 4588 for (int32_t Register : List) { |
| 4589 if (!First) |
| 4590 Str << " "; |
| 4591 First = false; |
| 4592 Str << getRegName(Register, IceType_i32); |
| 4593 } |
| 4594 Str << "}\n"; |
| 4595 } |
| 4596 } |
| 4597 } |
| 4598 |
4533 template <> void ConstantInteger32::emit(GlobalContext *Ctx) const { | 4599 template <> void ConstantInteger32::emit(GlobalContext *Ctx) const { |
4534 if (!ALLOW_DUMP) | 4600 if (!ALLOW_DUMP) |
4535 return; | 4601 return; |
4536 Ostream &Str = Ctx->getStrEmit(); | 4602 Ostream &Str = Ctx->getStrEmit(); |
4537 Str << "$" << (int32_t)getValue(); | 4603 Str << "$" << (int32_t)getValue(); |
4538 } | 4604 } |
4539 | 4605 |
4540 template <> void ConstantInteger64::emit(GlobalContext *) const { | 4606 template <> void ConstantInteger64::emit(GlobalContext *) const { |
4541 llvm_unreachable("Not expecting to emit 64-bit integers"); | 4607 llvm_unreachable("Not expecting to emit 64-bit integers"); |
4542 } | 4608 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4652 } else if (IsConstant || IsExternal) | 4718 } else if (IsConstant || IsExternal) |
4653 Str << "\t.zero\t" << Size << "\n"; | 4719 Str << "\t.zero\t" << Size << "\n"; |
4654 // Size is part of .comm. | 4720 // Size is part of .comm. |
4655 | 4721 |
4656 if (IsConstant || HasNonzeroInitializer || IsExternal) | 4722 if (IsConstant || HasNonzeroInitializer || IsExternal) |
4657 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4723 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4658 // Size is part of .comm. | 4724 // Size is part of .comm. |
4659 } | 4725 } |
4660 | 4726 |
4661 } // end of namespace Ice | 4727 } // end of namespace Ice |
OLD | NEW |