| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// |
| 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 /// \file | 10 /// \file |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 // Look for: | 518 // Look for: |
| 519 // a = Load addr | 519 // a = Load addr |
| 520 // b = <op> a, other | 520 // b = <op> a, other |
| 521 // Store b, addr | 521 // Store b, addr |
| 522 // Change to: | 522 // Change to: |
| 523 // a = Load addr | 523 // a = Load addr |
| 524 // b = <op> a, other | 524 // b = <op> a, other |
| 525 // x = FakeDef | 525 // x = FakeDef |
| 526 // RMW <op>, addr, other, x | 526 // RMW <op>, addr, other, x |
| 527 // b = Store b, addr, x | 527 // b = Store b, addr, x |
| 528 // Note that inferTwoAddress() makes sure setDestNonKillable() gets | 528 // Note that inferTwoAddress() makes sure setDestRedefined() gets called |
| 529 // called on the updated Store instruction, to avoid liveness problems | 529 // on the updated Store instruction, to avoid liveness problems later. |
| 530 // later. | |
| 531 // | 530 // |
| 532 // With this transformation, the Store instruction acquires a Dest | 531 // With this transformation, the Store instruction acquires a Dest |
| 533 // variable and is now subject to dead code elimination if there are no | 532 // variable and is now subject to dead code elimination if there are no |
| 534 // more uses of "b". Variable "x" is a beacon for determining whether | 533 // more uses of "b". Variable "x" is a beacon for determining whether the |
| 535 // the Store instruction gets dead-code eliminated. If the Store | 534 // Store instruction gets dead-code eliminated. If the Store instruction |
| 536 // instruction is eliminated, then it must be the case that the RMW | 535 // is eliminated, then it must be the case that the RMW instruction ends |
| 537 // instruction ends x's live range, and therefore the RMW instruction | 536 // x's live range, and therefore the RMW instruction will be retained and |
| 538 // will be retained and later lowered. On the other hand, if the RMW | 537 // later lowered. On the other hand, if the RMW instruction does not end |
| 539 // instruction does not end x's live range, then the Store instruction | 538 // x's live range, then the Store instruction must still be present, and |
| 540 // must still be present, and therefore the RMW instruction is ignored | 539 // therefore the RMW instruction is ignored during lowering because it is |
| 541 // during lowering because it is redundant with the Store instruction. | 540 // redundant with the Store instruction. |
| 542 // | 541 // |
| 543 // Note that if "a" has further uses, the RMW transformation may still | 542 // Note that if "a" has further uses, the RMW transformation may still |
| 544 // trigger, resulting in two loads and one store, which is worse than the | 543 // trigger, resulting in two loads and one store, which is worse than the |
| 545 // original one load and one store. However, this is probably rare, and | 544 // original one load and one store. However, this is probably rare, and |
| 546 // caching probably keeps it just as fast. | 545 // caching probably keeps it just as fast. |
| 547 if (!isSameMemAddressOperand<Machine>(Load->getSourceAddress(), | 546 if (!isSameMemAddressOperand<Machine>(Load->getSourceAddress(), |
| 548 Store->getAddr())) | 547 Store->getAddr())) |
| 549 continue; | 548 continue; |
| 550 Operand *ArithSrcFromLoad = Arith->getSrc(0); | 549 Operand *ArithSrcFromLoad = Arith->getSrc(0); |
| 551 Operand *ArithSrcOther = Arith->getSrc(1); | 550 Operand *ArithSrcOther = Arith->getSrc(1); |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 // somewhat arbitrary choice of 3. | 1026 // somewhat arbitrary choice of 3. |
| 1028 const uint32_t MaxOpsForOptimizedMul = 3; | 1027 const uint32_t MaxOpsForOptimizedMul = 3; |
| 1029 if (CountOps > MaxOpsForOptimizedMul) | 1028 if (CountOps > MaxOpsForOptimizedMul) |
| 1030 return false; | 1029 return false; |
| 1031 _mov(T, Src0); | 1030 _mov(T, Src0); |
| 1032 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1031 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1033 for (uint32_t i = 0; i < Count9; ++i) { | 1032 for (uint32_t i = 0; i < Count9; ++i) { |
| 1034 const uint16_t Shift = 3; // log2(9-1) | 1033 const uint16_t Shift = 3; // log2(9-1) |
| 1035 _lea(T, | 1034 _lea(T, |
| 1036 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); | 1035 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); |
| 1037 _set_dest_nonkillable(); | |
| 1038 } | 1036 } |
| 1039 for (uint32_t i = 0; i < Count5; ++i) { | 1037 for (uint32_t i = 0; i < Count5; ++i) { |
| 1040 const uint16_t Shift = 2; // log2(5-1) | 1038 const uint16_t Shift = 2; // log2(5-1) |
| 1041 _lea(T, | 1039 _lea(T, |
| 1042 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); | 1040 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); |
| 1043 _set_dest_nonkillable(); | |
| 1044 } | 1041 } |
| 1045 for (uint32_t i = 0; i < Count3; ++i) { | 1042 for (uint32_t i = 0; i < Count3; ++i) { |
| 1046 const uint16_t Shift = 1; // log2(3-1) | 1043 const uint16_t Shift = 1; // log2(3-1) |
| 1047 _lea(T, | 1044 _lea(T, |
| 1048 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); | 1045 Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift)); |
| 1049 _set_dest_nonkillable(); | |
| 1050 } | 1046 } |
| 1051 if (Count2) { | 1047 if (Count2) { |
| 1052 _shl(T, Ctx->getConstantInt(Ty, Count2)); | 1048 _shl(T, Ctx->getConstantInt(Ty, Count2)); |
| 1053 } | 1049 } |
| 1054 if (Src1IsNegative) | 1050 if (Src1IsNegative) |
| 1055 _neg(T); | 1051 _neg(T); |
| 1056 _mov(Dest, T); | 1052 _mov(Dest, T); |
| 1057 return true; | 1053 return true; |
| 1058 } | 1054 } |
| 1059 | 1055 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 // t2 = shl t2, t1 | 1205 // t2 = shl t2, t1 |
| 1210 // test t1, 0x20 | 1206 // test t1, 0x20 |
| 1211 // je L1 | 1207 // je L1 |
| 1212 // use(t3) | 1208 // use(t3) |
| 1213 // t3 = t2 | 1209 // t3 = t2 |
| 1214 // t2 = 0 | 1210 // t2 = 0 |
| 1215 _shld(T_3, T_2, T_1); | 1211 _shld(T_3, T_2, T_1); |
| 1216 _shl(T_2, T_1); | 1212 _shl(T_2, T_1); |
| 1217 _test(T_1, BitTest); | 1213 _test(T_1, BitTest); |
| 1218 _br(Traits::Cond::Br_e, Label); | 1214 _br(Traits::Cond::Br_e, Label); |
| 1219 // T_2 and T_3 are being assigned again because of the intra-block | 1215 // T_2 and T_3 are being assigned again because of the intra-block control |
| 1220 // control flow, so we need the _mov_nonkillable variant to avoid | 1216 // flow, so we need the _mov_redefined variant to avoid liveness problems. |
| 1221 // liveness problems. | 1217 _mov_redefined(T_3, T_2); |
| 1222 _mov_nonkillable(T_3, T_2); | 1218 _mov_redefined(T_2, Zero); |
| 1223 _mov_nonkillable(T_2, Zero); | |
| 1224 } break; | 1219 } break; |
| 1225 case InstArithmetic::Lshr: { | 1220 case InstArithmetic::Lshr: { |
| 1226 // a=b>>c (unsigned) ==> | 1221 // a=b>>c (unsigned) ==> |
| 1227 // t2 = shrd t2, t3, t1 | 1222 // t2 = shrd t2, t3, t1 |
| 1228 // t3 = shr t3, t1 | 1223 // t3 = shr t3, t1 |
| 1229 // test t1, 0x20 | 1224 // test t1, 0x20 |
| 1230 // je L1 | 1225 // je L1 |
| 1231 // use(t2) | 1226 // use(t2) |
| 1232 // t2 = t3 | 1227 // t2 = t3 |
| 1233 // t3 = 0 | 1228 // t3 = 0 |
| 1234 _shrd(T_2, T_3, T_1); | 1229 _shrd(T_2, T_3, T_1); |
| 1235 _shr(T_3, T_1); | 1230 _shr(T_3, T_1); |
| 1236 _test(T_1, BitTest); | 1231 _test(T_1, BitTest); |
| 1237 _br(Traits::Cond::Br_e, Label); | 1232 _br(Traits::Cond::Br_e, Label); |
| 1238 // T_2 and T_3 are being assigned again because of the intra-block | 1233 // T_2 and T_3 are being assigned again because of the intra-block control |
| 1239 // control flow, so we need the _mov_nonkillable variant to avoid | 1234 // flow, so we need the _mov_redefined variant to avoid liveness problems. |
| 1240 // liveness problems. | 1235 _mov_redefined(T_2, T_3); |
| 1241 _mov_nonkillable(T_2, T_3); | 1236 _mov_redefined(T_3, Zero); |
| 1242 _mov_nonkillable(T_3, Zero); | |
| 1243 } break; | 1237 } break; |
| 1244 case InstArithmetic::Ashr: { | 1238 case InstArithmetic::Ashr: { |
| 1245 // a=b>>c (signed) ==> | 1239 // a=b>>c (signed) ==> |
| 1246 // t2 = shrd t2, t3, t1 | 1240 // t2 = shrd t2, t3, t1 |
| 1247 // t3 = sar t3, t1 | 1241 // t3 = sar t3, t1 |
| 1248 // test t1, 0x20 | 1242 // test t1, 0x20 |
| 1249 // je L1 | 1243 // je L1 |
| 1250 // use(t2) | 1244 // use(t2) |
| 1251 // t2 = t3 | 1245 // t2 = t3 |
| 1252 // t3 = sar t3, 0x1f | 1246 // t3 = sar t3, 0x1f |
| 1253 Constant *SignExtend = Ctx->getConstantInt32(0x1f); | 1247 Constant *SignExtend = Ctx->getConstantInt32(0x1f); |
| 1254 _shrd(T_2, T_3, T_1); | 1248 _shrd(T_2, T_3, T_1); |
| 1255 _sar(T_3, T_1); | 1249 _sar(T_3, T_1); |
| 1256 _test(T_1, BitTest); | 1250 _test(T_1, BitTest); |
| 1257 _br(Traits::Cond::Br_e, Label); | 1251 _br(Traits::Cond::Br_e, Label); |
| 1258 // T_2 and T_3 are being assigned again because of the intra-block | 1252 // T_2 and T_3 are being assigned again because of the intra-block control |
| 1259 // control flow, so T_2 needs the _mov_nonkillable variant to avoid | 1253 // flow, so T_2 needs the _mov_redefined variant to avoid liveness |
| 1260 // liveness problems. T_3 doesn't need special treatment because it is | 1254 // problems. T_3 doesn't need special treatment because it is reassigned |
| 1261 // reassigned via _sar instead of _mov. | 1255 // via _sar instead of _mov. |
| 1262 _mov_nonkillable(T_2, T_3); | 1256 _mov_redefined(T_2, T_3); |
| 1263 _sar(T_3, SignExtend); | 1257 _sar(T_3, SignExtend); |
| 1264 } break; | 1258 } break; |
| 1265 } | 1259 } |
| 1266 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> | 1260 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> |
| 1267 // L1: | 1261 // L1: |
| 1268 // a.lo = t2 | 1262 // a.lo = t2 |
| 1269 // a.hi = t3 | 1263 // a.hi = t3 |
| 1270 Context.insert(Label); | 1264 Context.insert(Label); |
| 1271 _mov(DestLo, T_2); | 1265 _mov(DestLo, T_2); |
| 1272 _mov(DestHi, T_3); | 1266 _mov(DestHi, T_3); |
| (...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 _mov(Dest, Default); | 2602 _mov(Dest, Default); |
| 2609 if (HasC1) { | 2603 if (HasC1) { |
| 2610 typename Traits::Insts::Label *Label = | 2604 typename Traits::Insts::Label *Label = |
| 2611 Traits::Insts::Label::create(Func, this); | 2605 Traits::Insts::Label::create(Func, this); |
| 2612 _br(Traits::TableFcmp[Index].C1, Label); | 2606 _br(Traits::TableFcmp[Index].C1, Label); |
| 2613 if (HasC2) { | 2607 if (HasC2) { |
| 2614 _br(Traits::TableFcmp[Index].C2, Label); | 2608 _br(Traits::TableFcmp[Index].C2, Label); |
| 2615 } | 2609 } |
| 2616 Constant *NonDefault = | 2610 Constant *NonDefault = |
| 2617 Ctx->getConstantInt32(!Traits::TableFcmp[Index].Default); | 2611 Ctx->getConstantInt32(!Traits::TableFcmp[Index].Default); |
| 2618 _mov_nonkillable(Dest, NonDefault); | 2612 _mov_redefined(Dest, NonDefault); |
| 2619 Context.insert(Label); | 2613 Context.insert(Label); |
| 2620 } | 2614 } |
| 2621 } | 2615 } |
| 2622 | 2616 |
| 2623 template <class Machine> | 2617 template <class Machine> |
| 2624 void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) { | 2618 void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) { |
| 2625 Operand *Src0 = legalize(Inst->getSrc(0)); | 2619 Operand *Src0 = legalize(Inst->getSrc(0)); |
| 2626 Operand *Src1 = legalize(Inst->getSrc(1)); | 2620 Operand *Src1 = legalize(Inst->getSrc(1)); |
| 2627 Variable *Dest = Inst->getDest(); | 2621 Variable *Dest = Inst->getDest(); |
| 2628 | 2622 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 Traits::Insts::Label::create(Func, this); | 2763 Traits::Insts::Label::create(Func, this); |
| 2770 _mov(Dest, One); | 2764 _mov(Dest, One); |
| 2771 _cmp(Src0HiRM, Src1HiRI); | 2765 _cmp(Src0HiRM, Src1HiRI); |
| 2772 if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None) | 2766 if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None) |
| 2773 _br(Traits::TableIcmp64[Index].C1, LabelTrue); | 2767 _br(Traits::TableIcmp64[Index].C1, LabelTrue); |
| 2774 if (Traits::TableIcmp64[Index].C2 != Traits::Cond::Br_None) | 2768 if (Traits::TableIcmp64[Index].C2 != Traits::Cond::Br_None) |
| 2775 _br(Traits::TableIcmp64[Index].C2, LabelFalse); | 2769 _br(Traits::TableIcmp64[Index].C2, LabelFalse); |
| 2776 _cmp(Src0LoRM, Src1LoRI); | 2770 _cmp(Src0LoRM, Src1LoRI); |
| 2777 _br(Traits::TableIcmp64[Index].C3, LabelTrue); | 2771 _br(Traits::TableIcmp64[Index].C3, LabelTrue); |
| 2778 Context.insert(LabelFalse); | 2772 Context.insert(LabelFalse); |
| 2779 _mov_nonkillable(Dest, Zero); | 2773 _mov_redefined(Dest, Zero); |
| 2780 Context.insert(LabelTrue); | 2774 Context.insert(LabelTrue); |
| 2781 } | 2775 } |
| 2782 | 2776 |
| 2783 template <class Machine> | 2777 template <class Machine> |
| 2784 void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) { | 2778 void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) { |
| 2785 Operand *SourceVectNotLegalized = Inst->getSrc(0); | 2779 Operand *SourceVectNotLegalized = Inst->getSrc(0); |
| 2786 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); | 2780 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); |
| 2787 ConstantInteger32 *ElementIndex = | 2781 ConstantInteger32 *ElementIndex = |
| 2788 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2)); | 2782 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2)); |
| 2789 // Only constant indices are allowed in PNaCl IR. | 2783 // Only constant indices are allowed in PNaCl IR. |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 case Intrinsics::Stacksave: { | 3236 case Intrinsics::Stacksave: { |
| 3243 Variable *esp = | 3237 Variable *esp = |
| 3244 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); | 3238 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); |
| 3245 Variable *Dest = Instr->getDest(); | 3239 Variable *Dest = Instr->getDest(); |
| 3246 _mov(Dest, esp); | 3240 _mov(Dest, esp); |
| 3247 return; | 3241 return; |
| 3248 } | 3242 } |
| 3249 case Intrinsics::Stackrestore: { | 3243 case Intrinsics::Stackrestore: { |
| 3250 Variable *esp = | 3244 Variable *esp = |
| 3251 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); | 3245 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); |
| 3252 _mov_nonkillable(esp, Instr->getArg(0)); | 3246 _mov_redefined(esp, Instr->getArg(0)); |
| 3253 return; | 3247 return; |
| 3254 } | 3248 } |
| 3255 case Intrinsics::Trap: | 3249 case Intrinsics::Trap: |
| 3256 _ud2(); | 3250 _ud2(); |
| 3257 return; | 3251 return; |
| 3258 case Intrinsics::UnknownIntrinsic: | 3252 case Intrinsics::UnknownIntrinsic: |
| 3259 Func->setError("Should not be lowering UnknownIntrinsic"); | 3253 Func->setError("Should not be lowering UnknownIntrinsic"); |
| 3260 return; | 3254 return; |
| 3261 } | 3255 } |
| 3262 return; | 3256 return; |
| (...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4381 if (typeWidthInBytes(DestTy) == 1 || isFloatingType(DestTy)) { | 4375 if (typeWidthInBytes(DestTy) == 1 || isFloatingType(DestTy)) { |
| 4382 // The cmov instruction doesn't allow 8-bit or FP operands, so we need | 4376 // The cmov instruction doesn't allow 8-bit or FP operands, so we need |
| 4383 // explicit control flow. | 4377 // explicit control flow. |
| 4384 // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1: | 4378 // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1: |
| 4385 typename Traits::Insts::Label *Label = | 4379 typename Traits::Insts::Label *Label = |
| 4386 Traits::Insts::Label::create(Func, this); | 4380 Traits::Insts::Label::create(Func, this); |
| 4387 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm); | 4381 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm); |
| 4388 _mov(Dest, SrcT); | 4382 _mov(Dest, SrcT); |
| 4389 _br(Cond, Label); | 4383 _br(Cond, Label); |
| 4390 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm); | 4384 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm); |
| 4391 _mov_nonkillable(Dest, SrcF); | 4385 _mov_redefined(Dest, SrcF); |
| 4392 Context.insert(Label); | 4386 Context.insert(Label); |
| 4393 return; | 4387 return; |
| 4394 } | 4388 } |
| 4395 // mov t, SrcF; cmov_cond t, SrcT; mov dest, t | 4389 // mov t, SrcF; cmov_cond t, SrcT; mov dest, t |
| 4396 // But if SrcT is immediate, we might be able to do better, as the cmov | 4390 // But if SrcT is immediate, we might be able to do better, as the cmov |
| 4397 // instruction doesn't allow an immediate operand: | 4391 // instruction doesn't allow an immediate operand: |
| 4398 // mov t, SrcT; cmov_!cond t, SrcF; mov dest, t | 4392 // mov t, SrcT; cmov_!cond t, SrcF; mov dest, t |
| 4399 if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) { | 4393 if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) { |
| 4400 std::swap(SrcT, SrcF); | 4394 std::swap(SrcT, SrcF); |
| 4401 Cond = InstX86Base<Machine>::getOppositeCondition(Cond); | 4395 Cond = InstX86Base<Machine>::getOppositeCondition(Cond); |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5217 ++TyIndex; | 5211 ++TyIndex; |
| 5218 uint32_t MaxIndex = MaxSize == NoSizeLimit | 5212 uint32_t MaxIndex = MaxSize == NoSizeLimit |
| 5219 ? llvm::array_lengthof(TypeForSize) - 1 | 5213 ? llvm::array_lengthof(TypeForSize) - 1 |
| 5220 : llvm::findLastSet(MaxSize, llvm::ZB_Undefined); | 5214 : llvm::findLastSet(MaxSize, llvm::ZB_Undefined); |
| 5221 return TypeForSize[std::min(TyIndex, MaxIndex)]; | 5215 return TypeForSize[std::min(TyIndex, MaxIndex)]; |
| 5222 } | 5216 } |
| 5223 | 5217 |
| 5224 template <class Machine> void TargetX86Base<Machine>::postLower() { | 5218 template <class Machine> void TargetX86Base<Machine>::postLower() { |
| 5225 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 5219 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
| 5226 return; | 5220 return; |
| 5227 inferTwoAddress(); | 5221 markRedefinitions(); |
| 5228 } | 5222 } |
| 5229 | 5223 |
| 5230 template <class Machine> | 5224 template <class Machine> |
| 5231 void TargetX86Base<Machine>::makeRandomRegisterPermutation( | 5225 void TargetX86Base<Machine>::makeRandomRegisterPermutation( |
| 5232 llvm::SmallVectorImpl<int32_t> &Permutation, | 5226 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 5233 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 5227 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
| 5234 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, | 5228 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, |
| 5235 ExcludeRegisters, Salt); | 5229 ExcludeRegisters, Salt); |
| 5236 } | 5230 } |
| 5237 | 5231 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5304 // chain. So we add RegNum argument here. Note we use 'lea' instruction | 5298 // chain. So we add RegNum argument here. Note we use 'lea' instruction |
| 5305 // instead of 'xor' to avoid affecting the flags. | 5299 // instead of 'xor' to avoid affecting the flags. |
| 5306 Variable *Reg = makeReg(IceType_i32, RegNum); | 5300 Variable *Reg = makeReg(IceType_i32, RegNum); |
| 5307 ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate); | 5301 ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate); |
| 5308 uint32_t Value = Integer->getValue(); | 5302 uint32_t Value = Integer->getValue(); |
| 5309 uint32_t Cookie = Func->getConstantBlindingCookie(); | 5303 uint32_t Cookie = Func->getConstantBlindingCookie(); |
| 5310 _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value)); | 5304 _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value)); |
| 5311 Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie); | 5305 Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie); |
| 5312 _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset, | 5306 _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset, |
| 5313 nullptr, 0)); | 5307 nullptr, 0)); |
| 5314 // make sure liveness analysis won't kill this variable, otherwise a | |
| 5315 // liveness assertion will be triggered. | |
| 5316 _set_dest_nonkillable(); | |
| 5317 if (Immediate->getType() != IceType_i32) { | 5308 if (Immediate->getType() != IceType_i32) { |
| 5318 Variable *TruncReg = makeReg(Immediate->getType(), RegNum); | 5309 Variable *TruncReg = makeReg(Immediate->getType(), RegNum); |
| 5319 _mov(TruncReg, Reg); | 5310 _mov(TruncReg, Reg); |
| 5320 return TruncReg; | 5311 return TruncReg; |
| 5321 } | 5312 } |
| 5322 return Reg; | 5313 return Reg; |
| 5323 } | 5314 } |
| 5324 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) { | 5315 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) { |
| 5325 // pool the constant | 5316 // pool the constant |
| 5326 // FROM: | 5317 // FROM: |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5393 | 5384 |
| 5394 typename Traits::X86OperandMem *TempMemOperand = | 5385 typename Traits::X86OperandMem *TempMemOperand = |
| 5395 Traits::X86OperandMem::create(Func, MemOperand->getType(), | 5386 Traits::X86OperandMem::create(Func, MemOperand->getType(), |
| 5396 MemOperand->getBase(), Mask1); | 5387 MemOperand->getBase(), Mask1); |
| 5397 // If we have already assigned a physical register, we must come from | 5388 // If we have already assigned a physical register, we must come from |
| 5398 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse | 5389 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse |
| 5399 // the assigned register as this assignment is that start of its | 5390 // the assigned register as this assignment is that start of its |
| 5400 // use-def chain. So we add RegNum argument here. | 5391 // use-def chain. So we add RegNum argument here. |
| 5401 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum); | 5392 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum); |
| 5402 _lea(RegTemp, TempMemOperand); | 5393 _lea(RegTemp, TempMemOperand); |
| 5403 // As source operand doesn't use the dstreg, we don't need to add | |
| 5404 // _set_dest_nonkillable(). But if we use the same Dest Reg, that is, | |
| 5405 // with RegNum assigned, we should add this _set_dest_nonkillable() | |
| 5406 if (RegNum != Variable::NoRegister) | |
| 5407 _set_dest_nonkillable(); | |
| 5408 | 5394 |
| 5409 typename Traits::X86OperandMem *NewMemOperand = | 5395 typename Traits::X86OperandMem *NewMemOperand = |
| 5410 Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp, | 5396 Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp, |
| 5411 Mask2, MemOperand->getIndex(), | 5397 Mask2, MemOperand->getIndex(), |
| 5412 MemOperand->getShift(), | 5398 MemOperand->getShift(), |
| 5413 MemOperand->getSegmentRegister()); | 5399 MemOperand->getSegmentRegister()); |
| 5414 | 5400 |
| 5415 // Label this memory operand as randomized, so we won't randomize it | 5401 // Label this memory operand as randomized, so we won't randomize it |
| 5416 // again in case we call legalize() multiple times on this memory | 5402 // again in case we call legalize() multiple times on this memory |
| 5417 // operand. | 5403 // operand. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5450 _mov(RegTemp, SymbolOperand); | 5436 _mov(RegTemp, SymbolOperand); |
| 5451 // If we have a base variable here, we should add the lea instruction | 5437 // If we have a base variable here, we should add the lea instruction |
| 5452 // to add the value of the base variable to RegTemp. If there is no | 5438 // to add the value of the base variable to RegTemp. If there is no |
| 5453 // base variable, we won't need this lea instruction. | 5439 // base variable, we won't need this lea instruction. |
| 5454 if (MemOperand->getBase()) { | 5440 if (MemOperand->getBase()) { |
| 5455 typename Traits::X86OperandMem *CalculateOperand = | 5441 typename Traits::X86OperandMem *CalculateOperand = |
| 5456 Traits::X86OperandMem::create( | 5442 Traits::X86OperandMem::create( |
| 5457 Func, MemOperand->getType(), MemOperand->getBase(), nullptr, | 5443 Func, MemOperand->getType(), MemOperand->getBase(), nullptr, |
| 5458 RegTemp, 0, MemOperand->getSegmentRegister()); | 5444 RegTemp, 0, MemOperand->getSegmentRegister()); |
| 5459 _lea(RegTemp, CalculateOperand); | 5445 _lea(RegTemp, CalculateOperand); |
| 5460 _set_dest_nonkillable(); | |
| 5461 } | 5446 } |
| 5462 typename Traits::X86OperandMem *NewMemOperand = | 5447 typename Traits::X86OperandMem *NewMemOperand = |
| 5463 Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp, | 5448 Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp, |
| 5464 nullptr, MemOperand->getIndex(), | 5449 nullptr, MemOperand->getIndex(), |
| 5465 MemOperand->getShift(), | 5450 MemOperand->getShift(), |
| 5466 MemOperand->getSegmentRegister()); | 5451 MemOperand->getSegmentRegister()); |
| 5467 return NewMemOperand; | 5452 return NewMemOperand; |
| 5468 } | 5453 } |
| 5469 assert("Unsupported -randomize-pool-immediates option" && false); | 5454 assert("Unsupported -randomize-pool-immediates option" && false); |
| 5470 } | 5455 } |
| 5471 } | 5456 } |
| 5472 // the offset is not eligible for blinding or pooling, return the original | 5457 // the offset is not eligible for blinding or pooling, return the original |
| 5473 // mem operand | 5458 // mem operand |
| 5474 return MemOperand; | 5459 return MemOperand; |
| 5475 } | 5460 } |
| 5476 | 5461 |
| 5477 } // end of namespace X86Internal | 5462 } // end of namespace X86Internal |
| 5478 } // end of namespace Ice | 5463 } // end of namespace Ice |
| 5479 | 5464 |
| 5480 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5465 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |