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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1185703004: Add constant blinding/pooling option for X8632 code translation (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: reformat Created 5 years, 6 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 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 TypeToRegisterSet[IceType_i64] = IntegerRegisters; 431 TypeToRegisterSet[IceType_i64] = IntegerRegisters;
432 TypeToRegisterSet[IceType_f32] = FloatRegisters; 432 TypeToRegisterSet[IceType_f32] = FloatRegisters;
433 TypeToRegisterSet[IceType_f64] = FloatRegisters; 433 TypeToRegisterSet[IceType_f64] = FloatRegisters;
434 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 434 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
435 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 435 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
436 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 436 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
437 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 437 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
438 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 438 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
439 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 439 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
440 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 440 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
441
442 // qining: initialize the assistant pause flag
Jim Stichnoth 2015/06/12 23:48:18 "qining:"? (here and below) What does "assistant
qining 2015/06/17 04:28:53 Done. Removed
443 // for constant blinding and pooling.
444 // When this is set to true, all constant blinding
445 // and pooling will be disabled. This should be set to
446 // true for doLoadOpt() and advancedPhiLowering().
447 // Note, when a physical regs are available for the Dest
Jim Stichnoth 2015/06/12 23:48:18 I'm not 100% sure what this part of the comment me
448 // of Phi lowering assignment, we should set this flag to
449 // false to enable blinding/pooling for that instruction.
450 RandomizationPoolingPaused = false;
Jim Stichnoth 2015/06/12 23:48:17 Do this simple initialization in the initializer l
qining 2015/06/13 00:41:26 Agree, but should we still leave the comments (may
qining 2015/06/17 04:28:54 Done.
441 } 451 }
442 452
443 void TargetX8632::translateO2() { 453 void TargetX8632::translateO2() {
444 TimerMarker T(TimerStack::TT_O2, Func); 454 TimerMarker T(TimerStack::TT_O2, Func);
445 455
446 if (!Ctx->getFlags().getPhiEdgeSplit()) { 456 if (!Ctx->getFlags().getPhiEdgeSplit()) {
447 // Lower Phi instructions. 457 // Lower Phi instructions.
448 Func->placePhiLoads(); 458 Func->placePhiLoads();
449 if (Func->hasError()) 459 if (Func->hasError())
450 return; 460 return;
(...skipping 24 matching lines...) Expand all
475 return; 485 return;
476 486
477 // TODO: It should be sufficient to use the fastest liveness 487 // TODO: It should be sufficient to use the fastest liveness
478 // calculation, i.e. livenessLightweight(). However, for some 488 // calculation, i.e. livenessLightweight(). However, for some
479 // reason that slows down the rest of the translation. Investigate. 489 // reason that slows down the rest of the translation. Investigate.
480 Func->liveness(Liveness_Basic); 490 Func->liveness(Liveness_Basic);
481 if (Func->hasError()) 491 if (Func->hasError())
482 return; 492 return;
483 Func->dump("After x86 address mode opt"); 493 Func->dump("After x86 address mode opt");
484 494
495 // qining: disable constant blinding or pooling for load optimization
496 bool RPLatchForDoLoadOpt = RandomizationPoolingPaused;
Jim Stichnoth 2015/06/12 23:48:17 You are using this pattern enough times (5?) that
qining 2015/06/17 04:28:54 Done.
497 RandomizationPoolingPaused = true;
485 doLoadOpt(); 498 doLoadOpt();
499 // qining: Resume constant blinding and pooling
500 RandomizationPoolingPaused = RPLatchForDoLoadOpt;
486 Func->genCode(); 501 Func->genCode();
487 if (Func->hasError()) 502 if (Func->hasError())
488 return; 503 return;
489 Func->dump("After x86 codegen"); 504 Func->dump("After x86 codegen");
490 505
491 // Register allocation. This requires instruction renumbering and 506 // Register allocation. This requires instruction renumbering and
492 // full liveness analysis. 507 // full liveness analysis.
493 Func->renumberInstructions(); 508 Func->renumberInstructions();
494 if (Func->hasError()) 509 if (Func->hasError())
495 return; 510 return;
496 Func->liveness(Liveness_Intervals); 511 Func->liveness(Liveness_Intervals);
497 if (Func->hasError()) 512 if (Func->hasError())
498 return; 513 return;
499 // Validate the live range computations. The expensive validation 514 // Validate the live range computations. The expensive validation
500 // call is deliberately only made when assertions are enabled. 515 // call is deliberately only made when assertions are enabled.
501 assert(Func->validateLiveness()); 516 assert(Func->validateLiveness());
502 // The post-codegen dump is done here, after liveness analysis and 517 // The post-codegen dump is done here, after liveness analysis and
503 // associated cleanup, to make the dump cleaner and more useful. 518 // associated cleanup, to make the dump cleaner and more useful.
504 Func->dump("After initial x8632 codegen"); 519 Func->dump("After initial x8632 codegen");
505 Func->getVMetadata()->init(VMK_All); 520 Func->getVMetadata()->init(VMK_All);
506 regAlloc(RAK_Global); 521 regAlloc(RAK_Global);
507 if (Func->hasError()) 522 if (Func->hasError())
508 return; 523 return;
509 Func->dump("After linear scan regalloc"); 524 Func->dump("After linear scan regalloc");
510 525
511 if (Ctx->getFlags().getPhiEdgeSplit()) { 526 if (Ctx->getFlags().getPhiEdgeSplit()) {
527 // : In general we need to pause constant blinding or pooling
Jim Stichnoth 2015/06/12 23:48:18 ":" ?
qining 2015/06/17 04:28:53 Done. Should I remove this comment?
528 // advanced phi lowering, unless the lowering assignment has a
Jim Stichnoth 2015/06/12 23:48:17 during advanced phi lowering
qining 2015/06/17 04:28:54 Done.
529 // physical register for the Dest Variable
530 bool RPLatchAdvancedPhiLowering = RandomizationPoolingPaused;
531 RandomizationPoolingPaused = true;
512 Func->advancedPhiLowering(); 532 Func->advancedPhiLowering();
533 // qining: recover the pause flag;
534 RandomizationPoolingPaused = RPLatchAdvancedPhiLowering;
513 Func->dump("After advanced Phi lowering"); 535 Func->dump("After advanced Phi lowering");
514 } 536 }
515 537
516 // Stack frame mapping. 538 // Stack frame mapping.
517 Func->genFrame(); 539 Func->genFrame();
518 if (Func->hasError()) 540 if (Func->hasError())
519 return; 541 return;
520 Func->dump("After stack frame mapping"); 542 Func->dump("After stack frame mapping");
521 543
522 Func->contractEmptyNodes(); 544 Func->contractEmptyNodes();
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 return RegNames[RegNum]; 777 return RegNames[RegNum];
756 } 778 }
757 } 779 }
758 780
759 void TargetX8632::emitVariable(const Variable *Var) const { 781 void TargetX8632::emitVariable(const Variable *Var) const {
760 Ostream &Str = Ctx->getStrEmit(); 782 Ostream &Str = Ctx->getStrEmit();
761 if (Var->hasReg()) { 783 if (Var->hasReg()) {
762 Str << "%" << getRegName(Var->getRegNum(), Var->getType()); 784 Str << "%" << getRegName(Var->getRegNum(), Var->getType());
763 return; 785 return;
764 } 786 }
765 if (Var->getWeight().isInf()) 787 if (Var->getWeight().isInf()) {
766 llvm_unreachable("Infinite-weight Variable has no register assigned"); 788 llvm_unreachable("Infinite-weight Variable has no register assigned");
789 }
767 int32_t Offset = Var->getStackOffset(); 790 int32_t Offset = Var->getStackOffset();
768 if (!hasFramePointer()) 791 if (!hasFramePointer())
769 Offset += getStackAdjustment(); 792 Offset += getStackAdjustment();
770 if (Offset) 793 if (Offset)
771 Str << Offset; 794 Str << Offset;
772 const Type FrameSPTy = IceType_i32; 795 const Type FrameSPTy = IceType_i32;
773 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")"; 796 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")";
774 } 797 }
775 798
776 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const { 799 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const {
777 if (Var->hasReg()) 800 if (Var->hasReg())
778 llvm_unreachable("Stack Variable has a register assigned"); 801 llvm_unreachable("Stack Variable has a register assigned");
779 if (Var->getWeight().isInf()) 802 if (Var->getWeight().isInf()) {
780 llvm_unreachable("Infinite-weight Variable has no register assigned"); 803 llvm_unreachable("Infinite-weight Variable has no register assigned");
804 }
781 int32_t Offset = Var->getStackOffset(); 805 int32_t Offset = Var->getStackOffset();
782 if (!hasFramePointer()) 806 if (!hasFramePointer())
783 Offset += getStackAdjustment(); 807 Offset += getStackAdjustment();
784 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset); 808 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset);
785 } 809 }
786 810
787 void TargetX8632::lowerArguments() { 811 void TargetX8632::lowerArguments() {
788 VarList &Args = Func->getArgs(); 812 VarList &Args = Func->getArgs();
789 // The first four arguments of vector type, regardless of their 813 // The first four arguments of vector type, regardless of their
790 // position relative to the other arguments in the argument list, are 814 // position relative to the other arguments in the argument list, are
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 Operand *TargetX8632::loOperand(Operand *Operand) { 1185 Operand *TargetX8632::loOperand(Operand *Operand) {
1162 assert(Operand->getType() == IceType_i64 || 1186 assert(Operand->getType() == IceType_i64 ||
1163 Operand->getType() == IceType_f64); 1187 Operand->getType() == IceType_f64);
1164 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1188 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1165 return Operand; 1189 return Operand;
1166 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1190 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1167 split64(Var); 1191 split64(Var);
1168 return Var->getLo(); 1192 return Var->getLo();
1169 } 1193 }
1170 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1194 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1171 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 1195 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
Jim Stichnoth 2015/06/12 23:48:18 Use cast<> instead of dyn_cast<>.
qining 2015/06/17 04:28:54 Done
1196 Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())));
Jim Stichnoth 2015/06/12 23:48:18 I think you should use int32_t instead of uint32_t
qining 2015/06/17 04:28:54 Done
1197 // check if we need to blind/pool the constant
1198 return randomizeOrPoolImmediate(ConstInt);
1172 } 1199 }
1173 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1200 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
1174 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 1201 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1175 Mem->getOffset(), Mem->getIndex(), 1202 Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
1176 Mem->getShift(), Mem->getSegmentRegister()); 1203 Mem->getShift(), Mem->getSegmentRegister());
1204 // Test if we should randomize or pool the offset, if so randomize it or
1205 // pool it then create mem operand with the blinded/pooled constant.
1206 // Otherwise, return the mem operand as ordinary mem operand.
1207 return randomizeOrPoolImmediate(MemOperand);
1177 } 1208 }
1178 llvm_unreachable("Unsupported operand type"); 1209 llvm_unreachable("Unsupported operand type");
1179 return nullptr; 1210 return nullptr;
1180 } 1211 }
1181 1212
1182 Operand *TargetX8632::hiOperand(Operand *Operand) { 1213 Operand *TargetX8632::hiOperand(Operand *Operand) {
1183 assert(Operand->getType() == IceType_i64 || 1214 assert(Operand->getType() == IceType_i64 ||
1184 Operand->getType() == IceType_f64); 1215 Operand->getType() == IceType_f64);
1185 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1216 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1186 return Operand; 1217 return Operand;
1187 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1218 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1188 split64(Var); 1219 split64(Var);
1189 return Var->getHi(); 1220 return Var->getHi();
1190 } 1221 }
1191 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1222 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1192 return Ctx->getConstantInt32( 1223 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
Jim Stichnoth 2015/06/12 23:48:18 cast<>
qining 2015/06/17 04:28:54 Done
1193 static_cast<uint32_t>(Const->getValue() >> 32)); 1224 Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue() >> 32)));
Jim Stichnoth 2015/06/12 23:48:17 int32_t
qining 2015/06/17 04:28:54 Done
1225 // check if we need to blind/pool the constant
1226 return randomizeOrPoolImmediate(ConstInt);
1194 } 1227 }
1195 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1228 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
1196 Constant *Offset = Mem->getOffset(); 1229 Constant *Offset = Mem->getOffset();
1197 if (Offset == nullptr) { 1230 if (Offset == nullptr) {
1198 Offset = Ctx->getConstantInt32(4); 1231 Offset = Ctx->getConstantInt32(4);
1199 } else if (ConstantInteger32 *IntOffset = 1232 } else if (ConstantInteger32 *IntOffset =
1200 llvm::dyn_cast<ConstantInteger32>(Offset)) { 1233 llvm::dyn_cast<ConstantInteger32>(Offset)) {
1201 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue()); 1234 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue());
1202 } else if (ConstantRelocatable *SymOffset = 1235 } else if (ConstantRelocatable *SymOffset =
1203 llvm::dyn_cast<ConstantRelocatable>(Offset)) { 1236 llvm::dyn_cast<ConstantRelocatable>(Offset)) {
1204 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4)); 1237 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4));
1205 Offset = 1238 Offset =
1206 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(), 1239 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
1207 SymOffset->getSuppressMangling()); 1240 SymOffset->getSuppressMangling());
1208 } 1241 }
1209 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, 1242 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1210 Mem->getIndex(), Mem->getShift(), 1243 Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
1211 Mem->getSegmentRegister()); 1244 Mem->getShift(), Mem->getSegmentRegister());
1245 // Test if the Offset is an eligible i32 constants for randomization and
1246 // pooling. Blind/pool it if it is. Otherwise return as oridinary mem
1247 // operand.
1248 return randomizeOrPoolImmediate(MemOperand);
1212 } 1249 }
1213 llvm_unreachable("Unsupported operand type"); 1250 llvm_unreachable("Unsupported operand type");
1214 return nullptr; 1251 return nullptr;
1215 } 1252 }
1216 1253
1217 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, 1254 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
1218 RegSetMask Exclude) const { 1255 RegSetMask Exclude) const {
1219 llvm::SmallBitVector Registers(RegX8632::Reg_NUM); 1256 llvm::SmallBitVector Registers(RegX8632::Reg_NUM);
1220 1257
1221 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 1258 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 Operand *Src0Hi = hiOperand(Src0); 1869 Operand *Src0Hi = hiOperand(Src0);
1833 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1870 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1834 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1871 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1835 Variable *T_Lo = nullptr, *T_Hi = nullptr; 1872 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1836 _mov(T_Lo, Src0Lo); 1873 _mov(T_Lo, Src0Lo);
1837 _mov(DestLo, T_Lo); 1874 _mov(DestLo, T_Lo);
1838 _mov(T_Hi, Src0Hi); 1875 _mov(T_Hi, Src0Hi);
1839 _mov(DestHi, T_Hi); 1876 _mov(DestHi, T_Hi);
1840 } else { 1877 } else {
1841 Operand *RI; 1878 Operand *RI;
1842 if (Dest->hasReg()) 1879 if (Dest->hasReg()) {
1843 // If Dest already has a physical register, then legalize the 1880 // If Dest already has a physical register, then legalize the
1844 // Src operand into a Variable with the same register 1881 // Src operand into a Variable with the same register
1845 // assignment. This is mostly a workaround for advanced phi 1882 // assignment. This is mostly a workaround for advanced phi
1846 // lowering's ad-hoc register allocation which assumes no 1883 // lowering's ad-hoc register allocation which assumes no
1847 // register allocation is needed when at least one of the 1884 // register allocation is needed when at least one of the
1848 // operands is non-memory. 1885 // operands is non-memory.
1886
1887 // qining: if we have a physical register for the dest variable,
1888 // we can enable our constant blinding or pooling again. Note
1889 // this is only for advancedPhiLowering(), the flag flip should
1890 // leave no other side effect.
1891 bool RPLatchInLowerAssign = RandomizationPoolingPaused;
1892 RandomizationPoolingPaused = false;
1893
1849 RI = legalize(Src0, Legal_Reg, Dest->getRegNum()); 1894 RI = legalize(Src0, Legal_Reg, Dest->getRegNum());
1850 else 1895
1896 // qining: Resume constant blinding and pooling
1897 RandomizationPoolingPaused = RPLatchInLowerAssign;
1898 } else {
1851 // If Dest could be a stack operand, then RI must be a physical 1899 // If Dest could be a stack operand, then RI must be a physical
1852 // register or a scalar integer immediate. 1900 // register or a scalar integer immediate.
1853 RI = legalize(Src0, Legal_Reg | Legal_Imm); 1901 RI = legalize(Src0, Legal_Reg | Legal_Imm);
1902 }
1854 if (isVectorType(Dest->getType())) 1903 if (isVectorType(Dest->getType()))
1855 _movp(Dest, RI); 1904 _movp(Dest, RI);
1856 else 1905 else
1857 _mov(Dest, RI); 1906 _mov(Dest, RI);
1858 } 1907 }
1859 } 1908 }
1860 1909
1861 void TargetX8632::lowerBr(const InstBr *Inst) { 1910 void TargetX8632::lowerBr(const InstBr *Inst) {
1862 if (Inst->isUnconditional()) { 1911 if (Inst->isUnconditional()) {
1863 _br(Inst->getTargetUnconditional()); 1912 _br(Inst->getTargetUnconditional());
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 Context.insert( 3161 Context.insert(
3113 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); 3162 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
3114 return; 3163 return;
3115 } 3164 }
3116 case Intrinsics::AtomicRMW: 3165 case Intrinsics::AtomicRMW:
3117 if (!Intrinsics::isMemoryOrderValid( 3166 if (!Intrinsics::isMemoryOrderValid(
3118 ID, getConstantMemoryOrder(Instr->getArg(3)))) { 3167 ID, getConstantMemoryOrder(Instr->getArg(3)))) {
3119 Func->setError("Unexpected memory ordering for AtomicRMW"); 3168 Func->setError("Unexpected memory ordering for AtomicRMW");
3120 return; 3169 return;
3121 } 3170 }
3122 lowerAtomicRMW(Instr->getDest(), 3171 lowerAtomicRMW(
3123 static_cast<uint32_t>(llvm::cast<ConstantInteger32>( 3172 Instr->getDest(),
3124 Instr->getArg(0))->getValue()), 3173 static_cast<uint32_t>(
3125 Instr->getArg(1), Instr->getArg(2)); 3174 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()),
3175 Instr->getArg(1), Instr->getArg(2));
3126 return; 3176 return;
3127 case Intrinsics::AtomicStore: { 3177 case Intrinsics::AtomicStore: {
3128 if (!Intrinsics::isMemoryOrderValid( 3178 if (!Intrinsics::isMemoryOrderValid(
3129 ID, getConstantMemoryOrder(Instr->getArg(2)))) { 3179 ID, getConstantMemoryOrder(Instr->getArg(2)))) {
3130 Func->setError("Unexpected memory ordering for AtomicStore"); 3180 Func->setError("Unexpected memory ordering for AtomicStore");
3131 return; 3181 return;
3132 } 3182 }
3133 // We require the memory address to be naturally aligned. 3183 // We require the memory address to be naturally aligned.
3134 // Given that is the case, then normal stores are atomic. 3184 // Given that is the case, then normal stores are atomic.
3135 // Add a fence after the store to make it visible. 3185 // Add a fence after the store to make it visible.
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4318 } 4368 }
4319 } 4369 }
4320 4370
4321 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { _ud2(); } 4371 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { _ud2(); }
4322 4372
4323 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to 4373 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
4324 // preserve integrity of liveness analysis. Undef values are also 4374 // preserve integrity of liveness analysis. Undef values are also
4325 // turned into zeroes, since loOperand() and hiOperand() don't expect 4375 // turned into zeroes, since loOperand() and hiOperand() don't expect
4326 // Undef input. 4376 // Undef input.
4327 void TargetX8632::prelowerPhis() { 4377 void TargetX8632::prelowerPhis() {
4378 // Pause constant blinding or pooling, blinding or pooling will be done later
4379 // during phi lowering assignments
4380 RandomizationPoolingPaused = true;
4381
4328 CfgNode *Node = Context.getNode(); 4382 CfgNode *Node = Context.getNode();
4329 for (Inst &I : Node->getPhis()) { 4383 for (Inst &I : Node->getPhis()) {
4330 auto Phi = llvm::dyn_cast<InstPhi>(&I); 4384 auto Phi = llvm::dyn_cast<InstPhi>(&I);
4331 if (Phi->isDeleted()) 4385 if (Phi->isDeleted())
4332 continue; 4386 continue;
4333 Variable *Dest = Phi->getDest(); 4387 Variable *Dest = Phi->getDest();
4334 if (Dest->getType() == IceType_i64) { 4388 if (Dest->getType() == IceType_i64) {
4335 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 4389 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
4336 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 4390 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
4337 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo); 4391 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
4338 InstPhi *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi); 4392 InstPhi *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi);
4339 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { 4393 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
4340 Operand *Src = Phi->getSrc(I); 4394 Operand *Src = Phi->getSrc(I);
4341 CfgNode *Label = Phi->getLabel(I); 4395 CfgNode *Label = Phi->getLabel(I);
4342 if (llvm::isa<ConstantUndef>(Src)) 4396 if (llvm::isa<ConstantUndef>(Src))
4343 Src = Ctx->getConstantZero(Dest->getType()); 4397 Src = Ctx->getConstantZero(Dest->getType());
4344 PhiLo->addArgument(loOperand(Src), Label); 4398 PhiLo->addArgument(loOperand(Src), Label);
4345 PhiHi->addArgument(hiOperand(Src), Label); 4399 PhiHi->addArgument(hiOperand(Src), Label);
4346 } 4400 }
4347 Node->getPhis().push_back(PhiLo); 4401 Node->getPhis().push_back(PhiLo);
4348 Node->getPhis().push_back(PhiHi); 4402 Node->getPhis().push_back(PhiHi);
4349 Phi->setDeleted(); 4403 Phi->setDeleted();
4350 } 4404 }
4351 } 4405 }
4406
4407 // Recover the constant blinding/pooling state
4408 RandomizationPoolingPaused = false;
4352 } 4409 }
4353 4410
4354 namespace { 4411 namespace {
4355 4412
4356 bool isMemoryOperand(const Operand *Opnd) { 4413 bool isMemoryOperand(const Operand *Opnd) {
4357 if (const auto Var = llvm::dyn_cast<Variable>(Opnd)) 4414 if (const auto Var = llvm::dyn_cast<Variable>(Opnd))
4358 return !Var->hasReg(); 4415 return !Var->hasReg();
4359 // We treat vector undef values the same as a memory operand, 4416 // We treat vector undef values the same as a memory operand,
4360 // because they do in fact need a register to materialize the vector 4417 // because they do in fact need a register to materialize the vector
4361 // of zeroes into. 4418 // of zeroes into.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
4612 } 4669 }
4613 if (Index) { 4670 if (Index) {
4614 RegIndex = legalizeToVar(Index); 4671 RegIndex = legalizeToVar(Index);
4615 } 4672 }
4616 if (Base != RegBase || Index != RegIndex) { 4673 if (Base != RegBase || Index != RegIndex) {
4617 From = 4674 From =
4618 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex, 4675 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
4619 Mem->getShift(), Mem->getSegmentRegister()); 4676 Mem->getShift(), Mem->getSegmentRegister());
4620 } 4677 }
4621 4678
4679 // qining: For all Memory Operands, we do randomization/pooling from here
4680 From = randomizeOrPoolImmediate(llvm::dyn_cast<OperandX8632Mem>(From));
Jim Stichnoth 2015/06/12 23:48:17 You've already done a dyn_cast<>(From) in the encl
qining 2015/06/17 04:28:53 Done
4681
4622 if (!(Allowed & Legal_Mem)) { 4682 if (!(Allowed & Legal_Mem)) {
4623 From = copyToReg(From, RegNum); 4683 From = copyToReg(From, RegNum);
4624 } 4684 }
4625 return From; 4685 return From;
4626 } 4686 }
4627 if (llvm::isa<Constant>(From)) { 4687 if (llvm::isa<Constant>(From)) {
4628 if (llvm::isa<ConstantUndef>(From)) { 4688 if (llvm::isa<ConstantUndef>(From)) {
4629 // Lower undefs to zero. Another option is to lower undefs to an 4689 // Lower undefs to zero. Another option is to lower undefs to an
4630 // uninitialized register; however, using an uninitialized register 4690 // uninitialized register; however, using an uninitialized register
4631 // results in less predictable code. 4691 // results in less predictable code.
4632 // 4692 //
4633 // If in the future the implementation is changed to lower undef 4693 // If in the future the implementation is changed to lower undef
4634 // values to uninitialized registers, a FakeDef will be needed: 4694 // values to uninitialized registers, a FakeDef will be needed:
4635 // Context.insert(InstFakeDef::create(Func, Reg)); 4695 // Context.insert(InstFakeDef::create(Func, Reg));
4636 // This is in order to ensure that the live range of Reg is not 4696 // This is in order to ensure that the live range of Reg is not
4637 // overestimated. If the constant being lowered is a 64 bit value, 4697 // overestimated. If the constant being lowered is a 64 bit value,
4638 // then the result should be split and the lo and hi components will 4698 // then the result should be split and the lo and hi components will
4639 // need to go in uninitialized registers. 4699 // need to go in uninitialized registers.
4640 if (isVectorType(Ty)) 4700 if (isVectorType(Ty))
4641 return makeVectorOfZeros(Ty, RegNum); 4701 return makeVectorOfZeros(Ty, RegNum);
4642 From = Ctx->getConstantZero(Ty); 4702 From = Ctx->getConstantZero(Ty);
4643 } 4703 }
4644 // There should be no constants of vector type (other than undef). 4704 // There should be no constants of vector type (other than undef).
4645 assert(!isVectorType(Ty)); 4705 assert(!isVectorType(Ty));
4706
4707 // If the operand is an 32 bit constant integer, we should check
4708 // whether we need to randomize it or pool it.
4709 if (From && llvm::isa<ConstantInteger32>(From)) {
Jim Stichnoth 2015/06/12 23:48:18 "From" must be non-null, so no need to test that.
qining 2015/06/17 04:28:54 Done
4710 Operand *NewFrom =
4711 randomizeOrPoolImmediate(llvm::cast<Constant>(From), RegNum);
Jim Stichnoth 2015/06/12 23:48:17 You can avoid the cast<> and the earlier isa<> che
qining 2015/06/17 04:28:54 Done
4712 if (NewFrom != From)
4713 return NewFrom;
4714 }
4715
4646 // Convert a scalar floating point constant into an explicit 4716 // Convert a scalar floating point constant into an explicit
4647 // memory operand. 4717 // memory operand.
4648 if (isScalarFloatingType(Ty)) { 4718 if (isScalarFloatingType(Ty)) {
4649 Variable *Base = nullptr; 4719 Variable *Base = nullptr;
4650 std::string Buffer; 4720 std::string Buffer;
4651 llvm::raw_string_ostream StrBuf(Buffer); 4721 llvm::raw_string_ostream StrBuf(Buffer);
4652 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); 4722 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
4653 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); 4723 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
4654 From = OperandX8632Mem::create(Func, Ty, Base, Offset); 4724 From = OperandX8632Mem::create(Func, Ty, Base, Offset);
4655 } 4725 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4699 bool IsSrc1ImmOrReg = false; 4769 bool IsSrc1ImmOrReg = false;
4700 if (llvm::isa<Constant>(Src1)) { 4770 if (llvm::isa<Constant>(Src1)) {
4701 IsSrc1ImmOrReg = true; 4771 IsSrc1ImmOrReg = true;
4702 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { 4772 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) {
4703 if (Var->hasReg()) 4773 if (Var->hasReg())
4704 IsSrc1ImmOrReg = true; 4774 IsSrc1ImmOrReg = true;
4705 } 4775 }
4706 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); 4776 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg);
4707 } 4777 }
4708 4778
4709 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Operand, Type Ty, 4779 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *operand, Type Ty,
Jim Stichnoth 2015/06/12 23:48:17 Variable names should be capitalized, so maybe Opn
qining 2015/06/17 04:28:54 Done, replaced with Opnd.
4710 bool DoLegalize) { 4780 bool DoLegalize) {
4711 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); 4781 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(operand);
4712 // It may be the case that address mode optimization already creates 4782 // It may be the case that address mode optimization already creates
4713 // an OperandX8632Mem, so in that case it wouldn't need another level 4783 // an OperandX8632Mem, so in that case it wouldn't need another level
4714 // of transformation. 4784 // of transformation.
4715 if (!Mem) { 4785 if (!Mem) {
4716 Variable *Base = llvm::dyn_cast<Variable>(Operand); 4786 Variable *Base = llvm::dyn_cast<Variable>(operand);
4717 Constant *Offset = llvm::dyn_cast<Constant>(Operand); 4787 Constant *Offset = llvm::dyn_cast<Constant>(operand);
4718 assert(Base || Offset); 4788 assert(Base || Offset);
4719 if (Offset) { 4789 if (Offset) {
4720 // Make sure Offset is not undef. 4790 // qining: during memory operand building, we do not
4791 // blind or pool the constant offset, we will work on
4792 // the whole memory operand later as one entity later,
4793 // this save one instruction. By turning blinding and
4794 // pooling off, we guarantee legalize(Offset) will return
4795 // a constant*
4796 bool RPLatchForMemOperandBuilding = RandomizationPoolingPaused;
4797 RandomizationPoolingPaused = true;
4798
4721 Offset = llvm::cast<Constant>(legalize(Offset)); 4799 Offset = llvm::cast<Constant>(legalize(Offset));
4800
4722 assert(llvm::isa<ConstantInteger32>(Offset) || 4801 assert(llvm::isa<ConstantInteger32>(Offset) ||
4723 llvm::isa<ConstantRelocatable>(Offset)); 4802 llvm::isa<ConstantRelocatable>(Offset));
4803
4804 // qining: Resume constant blinding and pooling
4805 RandomizationPoolingPaused = RPLatchForMemOperandBuilding;
4724 } 4806 }
4725 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 4807 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
4726 } 4808 }
4727 return llvm::cast<OperandX8632Mem>(DoLegalize ? legalize(Mem) : Mem); 4809 // qining: do legalization, which contains randomization/pooling
4810 // or do randomization/pooling.
4811 return llvm::cast<OperandX8632Mem>(
4812 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
4728 } 4813 }
4729 4814
4730 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 4815 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
4731 // There aren't any 64-bit integer registers for x86-32. 4816 // There aren't any 64-bit integer registers for x86-32.
4732 assert(Type != IceType_i64); 4817 assert(Type != IceType_i64);
4733 Variable *Reg = Func->makeVariable(Type); 4818 Variable *Reg = Func->makeVariable(Type);
4734 if (RegNum == Variable::NoRegister) 4819 if (RegNum == Variable::NoRegister)
4735 Reg->setWeightInfinite(); 4820 Reg->setWeightInfinite();
4736 else 4821 else
4737 Reg->setRegNum(RegNum); 4822 Reg->setRegNum(RegNum);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
4958 typedef ConstantDouble IceType; 5043 typedef ConstantDouble IceType;
4959 static const Type Ty = IceType_f64; 5044 static const Type Ty = IceType_f64;
4960 static const char *TypeName; 5045 static const char *TypeName;
4961 static const char *AsmTag; 5046 static const char *AsmTag;
4962 static const char *PrintfString; 5047 static const char *PrintfString;
4963 }; 5048 };
4964 const char *PoolTypeConverter<double>::TypeName = "double"; 5049 const char *PoolTypeConverter<double>::TypeName = "double";
4965 const char *PoolTypeConverter<double>::AsmTag = ".quad"; 5050 const char *PoolTypeConverter<double>::AsmTag = ".quad";
4966 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; 5051 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
4967 5052
5053 // Add converter for int type constant pooling
5054 template <> struct PoolTypeConverter<int> {
5055 typedef uint32_t PrimitiveIntType;
5056 typedef ConstantInteger32 IceType;
5057 static const Type Ty = IceType_i32;
5058 static const char *TypeName;
5059 static const char *AsmTag;
5060 static const char *PrintfString;
5061 };
5062 const char *PoolTypeConverter<int>::TypeName = "i32";
5063 const char *PoolTypeConverter<int>::AsmTag = ".long";
5064 const char *PoolTypeConverter<int>::PrintfString = "0x%x";
5065
4968 template <typename T> 5066 template <typename T>
4969 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) { 5067 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
4970 if (!ALLOW_DUMP) 5068 if (!ALLOW_DUMP)
4971 return; 5069 return;
4972 Ostream &Str = Ctx->getStrEmit(); 5070 Ostream &Str = Ctx->getStrEmit();
4973 Type Ty = T::Ty; 5071 Type Ty = T::Ty;
4974 SizeT Align = typeAlignInBytes(Ty); 5072 SizeT Align = typeAlignInBytes(Ty);
4975 ConstantList Pool = Ctx->getConstantPool(Ty); 5073 ConstantList Pool = Ctx->getConstantPool(Ty);
4976 5074
4977 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 5075 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
4978 << "\n"; 5076 << "\n";
4979 Str << "\t.align\t" << Align << "\n"; 5077 Str << "\t.align\t" << Align << "\n";
4980 for (Constant *C : Pool) { 5078 for (Constant *C : Pool) {
4981 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); 5079 typename T::IceType *Const = llvm::cast<typename T::IceType>(C);
5080 // When constant pooling turned on, only emit labels for eligible constants
5081 // If C is i32 constant and not large enough, we should ignore it here.
5082 if (llvm::isa<ConstantInteger32>(C) &&
5083 llvm::dyn_cast_or_null<ConstantInteger32>(C)
Jim Stichnoth 2015/06/12 23:48:18 Same comments here as in IceELFObjectWriter.cpp
qining 2015/06/17 04:28:54 Done. shouldBePooled will be checked before poolin
5084 ->shouldBeRandomizedOrPooled(Ctx) == false)
5085 continue;
4982 typename T::IceType::PrimType Value = Const->getValue(); 5086 typename T::IceType::PrimType Value = Const->getValue();
4983 // Use memcpy() to copy bits from Value into RawValue in a way 5087 // Use memcpy() to copy bits from Value into RawValue in a way
4984 // that avoids breaking strict-aliasing rules. 5088 // that avoids breaking strict-aliasing rules.
4985 typename T::PrimitiveIntType RawValue; 5089 typename T::PrimitiveIntType RawValue;
4986 memcpy(&RawValue, &Value, sizeof(Value)); 5090 memcpy(&RawValue, &Value, sizeof(Value));
4987 char buf[30]; 5091 char buf[30];
4988 int CharsPrinted = 5092 int CharsPrinted =
4989 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 5093 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
4990 assert(CharsPrinted >= 0 && 5094 assert(CharsPrinted >= 0 &&
4991 (size_t)CharsPrinted < llvm::array_lengthof(buf)); 5095 (size_t)CharsPrinted < llvm::array_lengthof(buf));
4992 (void)CharsPrinted; // avoid warnings if asserts are disabled 5096 (void)CharsPrinted; // avoid warnings if asserts are disabled
4993 Const->emitPoolLabel(Str); 5097 Const->emitPoolLabel(Str);
4994 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " 5098 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
4995 << Value << "\n"; 5099 << Value << "\n";
4996 } 5100 }
4997 } 5101 }
4998 5102
4999 void TargetDataX8632::lowerConstants() const { 5103 void TargetDataX8632::lowerConstants() const {
5000 if (Ctx->getFlags().getDisableTranslation()) 5104 if (Ctx->getFlags().getDisableTranslation())
5001 return; 5105 return;
5002 // No need to emit constants from the int pool since (for x86) they 5106 // No need to emit constants from the int pool since (for x86) they
5003 // are embedded as immediates in the instructions, just emit float/double. 5107 // are embedded as immediates in the instructions, just emit float/double.
5004 switch (Ctx->getFlags().getOutFileType()) { 5108 switch (Ctx->getFlags().getOutFileType()) {
5005 case FT_Elf: { 5109 case FT_Elf: {
5006 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 5110 ELFObjectWriter *Writer = Ctx->getObjectWriter();
5111
5112 // If immediates pooling turned on, pool the integer constants
5113 if (Ctx->getFlags().shouldPoolImmediates())
5114 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
5115
5007 Writer->writeConstantPool<ConstantFloat>(IceType_f32); 5116 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
5008 Writer->writeConstantPool<ConstantDouble>(IceType_f64); 5117 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
5009 } break; 5118 } break;
5010 case FT_Asm: 5119 case FT_Asm:
5011 case FT_Iasm: { 5120 case FT_Iasm: {
5012 OstreamLocker L(Ctx); 5121 OstreamLocker L(Ctx);
5122
5123 // If immediates pooling turned on, pool the integer constants
5124 if (Ctx->getFlags().shouldPoolImmediates())
5125 emitConstantPool<PoolTypeConverter<int>>(Ctx);
5126
5013 emitConstantPool<PoolTypeConverter<float>>(Ctx); 5127 emitConstantPool<PoolTypeConverter<float>>(Ctx);
5014 emitConstantPool<PoolTypeConverter<double>>(Ctx); 5128 emitConstantPool<PoolTypeConverter<double>>(Ctx);
5015 } break; 5129 } break;
5016 } 5130 }
5017 } 5131 }
5018 5132
5019 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) 5133 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
5020 : TargetHeaderLowering(Ctx) {} 5134 : TargetHeaderLowering(Ctx) {}
5021 5135
5136 uint32_t TargetX8632::getRandomizationCookie() {
5137 static uint64_t cookie = 0;
Jim Stichnoth 2015/06/12 23:48:18 Don't use static non-const variables, as they are
qining 2015/06/17 04:28:54 Done. Moved getRandomizationCookie() and the cooki
5138 static bool cookie_initialized = false;
5139 if (!cookie_initialized) {
5140 RandomNumberGenerator &RNG = Ctx->getRNG();
5141 cookie =
5142 (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max() + 1);
5143 cookie_initialized = true;
5144 }
5145 return cookie;
5146 }
5147
5148 // Blind/pool an immediate value
5149 Operand *TargetX8632::randomizeOrPoolImmediate(Constant *immediate,
Jim Stichnoth 2015/06/12 23:48:18 Capitalize "immediate" arg name.
qining 2015/06/17 04:28:53 Done
5150 int32_t RegNum) {
5151 assert(llvm::isa<ConstantInteger32>(immediate) ||
5152 llvm::isa<ConstantRelocatable>(immediate));
5153 if (Ctx->getFlags().shouldNotRandomizeOrPoolImmediates() == true ||
5154 RandomizationPoolingPaused == true) {
5155 // immediates randomization/pool turned off
5156 return immediate;
5157 }
5158 if (llvm::isa<ConstantInteger32>(immediate) &&
5159 llvm::dyn_cast<ConstantInteger32>(immediate)
5160 ->shouldBeRandomizedOrPooled(Ctx)) {
Jim Stichnoth 2015/06/12 23:48:18 Call immediate->shouldBeRandomizedOrPooled(Ctx) di
qining 2015/06/17 04:28:54 Done. Changed to: if(Constant *C = dyn_cast_or_nul
5161 Ctx->statsUpdateRPImms();
5162 if (Ctx->getFlags().shouldRandomizeImmediates() == true) {
5163 // blind the constant
5164 // FROM:
5165 // imm
5166 // TO:
5167 // insert: mov imm+cookie, Reg
5168 // insert: lea -cookie[Reg], Reg
5169 // => Reg
5170 // if we have already assigned a phy register, we must come from
5171 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
Jim Stichnoth 2015/06/12 23:48:18 advancedPhiLowering
qining 2015/06/17 04:28:54 Done.
5172 // the assigned register as this assignment is that start of its use-def
5173 // chain. So we add RegNum argument here.
5174 Variable *Reg = makeReg(immediate->getType(), RegNum);
5175 ConstantInteger32 *integer = llvm::cast<ConstantInteger32>(immediate);
Jim Stichnoth 2015/06/12 23:48:18 Capitalize variable names
qining 2015/06/17 04:28:53 Done.
5176 uint32_t value = integer->getValue();
5177 uint64_t cookie = getRandomizationCookie();
Jim Stichnoth 2015/06/12 23:48:18 uint32_t
qining 2015/06/17 04:28:54 Done.
5178 _mov(Reg, Ctx->getConstantInt(IceType_i32, cookie + value));
5179 Constant *offset = Ctx->getConstantInt(IceType_i32, 0 - cookie);
5180 _lea(Reg, OperandX8632Mem::create(Func, offset->getType(), Reg, offset,
5181 NULL, 0));
5182 // make sure liveness analysis won't kill this variable, otherwise a
5183 // liveness
5184 // assertion will be triggered.
5185 _set_dest_nonkillable();
5186 return Reg;
5187 } else {
Jim Stichnoth 2015/06/12 23:48:18 Don't use this pattern: if (abc) { def;
qining 2015/06/17 04:28:54 Done. Changed to: if (abc) { return xyz; } if
5188 // pool the constant
5189 // FROM:
5190 // imm
5191 // TO:
5192 // insert: mov $label, Reg
5193 // => Reg
5194 assert(Ctx->getFlags().shouldPoolImmediates() == true);
5195 // if we have already assigned a phy register, we must come from
5196 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
Jim Stichnoth 2015/06/12 23:48:17 advancedPhiLowering
qining 2015/06/17 04:28:53 Done.
5197 // the assigned register as this assignment is that start of its use-def
5198 // chain. So we add RegNum argument here.
5199 Variable *Reg = makeReg(immediate->getType(), RegNum);
5200 IceString label;
5201 llvm::raw_string_ostream label_stream(label);
5202 immediate->emitPoolLabel(label_stream);
5203 Constant *symbol = Ctx->getConstantSym(0, label_stream.str(), true);
Jim Stichnoth 2015/06/12 23:48:17 Try to avoid using non-obvious constants as argume
qining 2015/06/17 04:28:54 Done.
5204 OperandX8632Mem *MemOperand =
5205 OperandX8632Mem::create(Func, immediate->getType(), NULL, symbol);
5206 _mov(Reg, MemOperand);
5207 return Reg;
5208 }
5209 } else {
5210 // the constant immediate is not eligible for blinding/pooling
5211 return immediate;
5212 }
5213 }
5214
5215 OperandX8632Mem *
5216 TargetX8632::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
5217 int32_t RegNum) {
5218 assert(llvm::isa<OperandX8632Mem>(MemOperand));
Jim Stichnoth 2015/06/12 23:48:18 This assert isn't very useful and should always su
qining 2015/06/17 04:28:53 Done. Changed to assert(MemOperand).
5219 if (Ctx->getFlags().shouldNotRandomizeOrPoolImmediates() == true ||
5220 RandomizationPoolingPaused == true) {
5221 // immediates randomization/pooling is turned off
5222 return MemOperand;
5223 }
5224
5225 if (MemOperand->getOffset() &&
Jim Stichnoth 2015/06/12 23:48:18 Something like this might be more compact: if (au
qining 2015/06/17 04:28:53 Done.
5226 llvm::isa<ConstantInteger32>(MemOperand->getOffset()) &&
5227 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
5228 ->shouldBeRandomizedOrPooled(Ctx)) {
5229 // The offset of this mem operand should be blinded or pooled
5230 Ctx->statsUpdateRPImms();
5231 if (Ctx->getFlags().shouldRandomizeImmediates() == true) {
5232 // blind the constant offset
5233 // FROM:
5234 // offset[base, index, shift]
5235 // TO:
5236 // insert: lea offset+cookie[base], RegTemp
5237 // => -cookie[RegTemp, index, shift]
5238 uint32_t value =
5239 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
5240 ->getValue();
5241 uint64_t cookie = getRandomizationCookie();
5242 Constant *mask1 = Ctx->getConstantInt(IceType_i32, cookie + value);
5243 Constant *mask2 = Ctx->getConstantInt(IceType_i32, 0 - cookie);
5244 // qining: We need to make sure the MemOperand->getBase() has a physical
5245 // register, if it is a variable!
5246 if (MemOperand->getBase() != NULL)
Jim Stichnoth 2015/06/12 23:48:18 nullptr, or just leave out the != part
qining 2015/06/17 04:28:54 Done.
5247 MemOperand->getBase()->setWeightInfinite();
Jim Stichnoth 2015/06/12 23:48:17 This will get you into trouble. The base variable
5248 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
5249 Func, MemOperand->getType(), MemOperand->getBase(), mask1);
5250 // if we have already assigned a phy register, we must come from
5251 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5252 // the assigned register as this assignment is that start of its use-def
5253 // chain. So we add RegNum argument here.
5254
5255 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum);
5256 _lea(RegTemp, TempMemOperand);
5257 // as srcreg doesn't include dstreg, we don't need to add
5258 // _set_dest_nonkillable()
5259 // qining: but if we use the same Dest Reg, that is, with RegNum
5260 // assigned, we should add this _set_dest_nonkillable()
5261 if (RegNum != Variable::NoRegister)
5262 _set_dest_nonkillable();
5263
5264 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5265 Func, MemOperand->getType(), RegTemp, mask2, MemOperand->getIndex(),
5266 MemOperand->getShift(), MemOperand->getSegmentRegister());
5267
5268 return NewMemOperand;
5269
5270 } else {
5271 // pool the constant offset
5272 // FROM:
5273 // offset[base, index, shift]
5274 // TO:
5275 // insert: mov $label, RegTemp
5276 // insert: lea [base, RegTemp], RegTemp
5277 // =>[RegTemp, index, shift]
5278 assert(Ctx->getFlags().shouldPoolImmediates() == true);
5279 // qining: Mem operand should never exist as source operands in phi
5280 // lowering
5281 // assignments, so there is no need to reuse any registers here.
5282 // However, for phi lowering, we should not ask for new physical
5283 // registers in general.
5284 // However, if we do meet MemOperand during phi lowering, we should not
5285 // blind or pool the immediates for now
5286 if (RegNum != Variable::NoRegister)
5287 return MemOperand;
5288 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType());
5289 IceString label;
5290 llvm::raw_string_ostream label_stream(label);
5291 MemOperand->getOffset()->emitPoolLabel(label_stream);
5292 Constant *symbol = Ctx->getConstantSym(0, label_stream.str(), true);
5293 OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
5294 Func, MemOperand->getOffset()->getType(), NULL, symbol);
5295 _mov(RegTemp, SymbolOperand);
5296 // qining: We need to make sure the MemOperand->getBase() has a physical
5297 // register! If we do not have base register here, we won't need an
5298 // extra lea instruction anymore.
5299 if (MemOperand->getBase() != NULL) {
5300 MemOperand->getBase()->setWeightInfinite();
5301 OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
5302 Func, MemOperand->getType(), MemOperand->getBase(), NULL, RegTemp,
5303 0, MemOperand->getSegmentRegister());
5304 _lea(RegTemp, CalculateOperand);
5305 _set_dest_nonkillable();
5306 }
5307 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5308 Func, MemOperand->getType(), RegTemp, NULL, MemOperand->getIndex(),
5309 MemOperand->getShift(), MemOperand->getSegmentRegister());
5310 return NewMemOperand;
5311 }
5312 } else {
5313 // the offset is not eligible for blinding or pooling, return the original
5314 // mem operand
5315 return MemOperand;
5316 }
5317 }
5022 } // end of namespace Ice 5318 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698