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

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1368993004: Subzero: Improve usability of liveness-related tools. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 5 years, 2 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/IceTargetLoweringX86Base.h ('k') | no next file » | 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/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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698