Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |