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

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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 #undef X 239 #undef X
240 // Repeat the static asserts with respect to the high-level table 240 // Repeat the static asserts with respect to the high-level table
241 // entries in case the high-level table has extra entries. 241 // entries in case the high-level table has extra entries.
242 #define X(tag, size, align, elts, elty, str) \ 242 #define X(tag, size, align, elts, elty, str) \
243 static_assert(_table1_##tag == _table2_##tag, \ 243 static_assert(_table1_##tag == _table2_##tag, \
244 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); 244 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
245 ICETYPE_TABLE 245 ICETYPE_TABLE
246 #undef X 246 #undef X
247 } // end of namespace dummy3 247 } // end of namespace dummy3
248 248
249 // A helper class to ease the settings of RandomizationPoolingPause
250 // to disable constant blinding or pooling for some translation phases.
251 class BoolFlagSaver {
252 BoolFlagSaver() = delete;
253 BoolFlagSaver(const BoolFlagSaver &) = delete;
254 BoolFlagSaver &operator=(const BoolFlagSaver &) = delete;
255
256 public:
257 BoolFlagSaver(bool &F, bool NewValue) : Flag(F) {
258 OldValue = F;
259 F = NewValue;
260 }
261 ~BoolFlagSaver() { Flag = OldValue; }
262
263 private:
264 bool &Flag;
265 bool OldValue;
266 };
267
249 } // end of anonymous namespace 268 } // end of anonymous namespace
250 269
251 BoolFoldingEntry::BoolFoldingEntry(Inst *I) 270 BoolFoldingEntry::BoolFoldingEntry(Inst *I)
252 : Instr(I), IsComplex(BoolFolding::hasComplexLowering(I)), IsLiveOut(true), 271 : Instr(I), IsComplex(BoolFolding::hasComplexLowering(I)), IsLiveOut(true),
253 NumUses(0) {} 272 NumUses(0) {}
254 273
255 BoolFolding::BoolFoldingProducerKind 274 BoolFolding::BoolFoldingProducerKind
256 BoolFolding::getProducerKind(const Inst *Instr) { 275 BoolFolding::getProducerKind(const Inst *Instr) {
257 if (llvm::isa<InstIcmp>(Instr)) { 276 if (llvm::isa<InstIcmp>(Instr)) {
258 if (Instr->getSrc(0)->getType() != IceType_i64) 277 if (Instr->getSrc(0)->getType() != IceType_i64)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 void TargetX8632::initNodeForLowering(CfgNode *Node) { 411 void TargetX8632::initNodeForLowering(CfgNode *Node) {
393 FoldingInfo.init(Node); 412 FoldingInfo.init(Node);
394 FoldingInfo.dump(Func); 413 FoldingInfo.dump(Func);
395 } 414 }
396 415
397 TargetX8632::TargetX8632(Cfg *Func) 416 TargetX8632::TargetX8632(Cfg *Func)
398 : TargetLowering(Func), 417 : TargetLowering(Func),
399 InstructionSet(static_cast<X86InstructionSet>( 418 InstructionSet(static_cast<X86InstructionSet>(
400 Func->getContext()->getFlags().getTargetInstructionSet() - 419 Func->getContext()->getFlags().getTargetInstructionSet() -
401 TargetInstructionSet::X86InstructionSet_Begin)), 420 TargetInstructionSet::X86InstructionSet_Begin)),
402 IsEbpBasedFrame(false), NeedsStackAlignment(false), 421 IsEbpBasedFrame(false), NeedsStackAlignment(false), SpillAreaSizeBytes(0),
403 SpillAreaSizeBytes(0) { 422 RandomizationPoolingPaused(false) {
404 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) == 423 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) ==
405 (TargetInstructionSet::X86InstructionSet_End - 424 (TargetInstructionSet::X86InstructionSet_End -
406 TargetInstructionSet::X86InstructionSet_Begin), 425 TargetInstructionSet::X86InstructionSet_Begin),
407 "X86InstructionSet range different from TargetInstructionSet"); 426 "X86InstructionSet range different from TargetInstructionSet");
408 // TODO: Don't initialize IntegerRegisters and friends every time. 427 // TODO: Don't initialize IntegerRegisters and friends every time.
409 // Instead, initialize in some sort of static initializer for the 428 // Instead, initialize in some sort of static initializer for the
410 // class. 429 // class.
411 llvm::SmallBitVector IntegerRegisters(RegX8632::Reg_NUM); 430 llvm::SmallBitVector IntegerRegisters(RegX8632::Reg_NUM);
412 llvm::SmallBitVector IntegerRegistersI8(RegX8632::Reg_NUM); 431 llvm::SmallBitVector IntegerRegistersI8(RegX8632::Reg_NUM);
413 llvm::SmallBitVector FloatRegisters(RegX8632::Reg_NUM); 432 llvm::SmallBitVector FloatRegisters(RegX8632::Reg_NUM);
(...skipping 17 matching lines...) Expand all
431 TypeToRegisterSet[IceType_i64] = IntegerRegisters; 450 TypeToRegisterSet[IceType_i64] = IntegerRegisters;
432 TypeToRegisterSet[IceType_f32] = FloatRegisters; 451 TypeToRegisterSet[IceType_f32] = FloatRegisters;
433 TypeToRegisterSet[IceType_f64] = FloatRegisters; 452 TypeToRegisterSet[IceType_f64] = FloatRegisters;
434 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 453 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
435 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 454 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
436 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 455 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
437 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 456 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
438 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 457 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
439 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 458 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
440 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 459 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
460
461 // qining: initialize the assistant pause flag
462 // for constant blinding and pooling.
463 // When this is set to true, all constant blinding
464 // and pooling will be disabled. This should be set to
465 // true for doLoadOpt() and advancedPhiLowering().
466 // Note, when a physical regs are available for the Dest
467 // of Phi lowering assignment, we should set this flag to
qining 2015/06/17 04:28:55 This will be removed soon.
468 // false to enable blinding/pooling for that instruction.
441 } 469 }
442 470
443 void TargetX8632::translateO2() { 471 void TargetX8632::translateO2() {
444 TimerMarker T(TimerStack::TT_O2, Func); 472 TimerMarker T(TimerStack::TT_O2, Func);
445 473
446 if (!Ctx->getFlags().getPhiEdgeSplit()) { 474 if (!Ctx->getFlags().getPhiEdgeSplit()) {
447 // Lower Phi instructions. 475 // Lower Phi instructions.
448 Func->placePhiLoads(); 476 Func->placePhiLoads();
449 if (Func->hasError()) 477 if (Func->hasError())
450 return; 478 return;
(...skipping 24 matching lines...) Expand all
475 return; 503 return;
476 504
477 // TODO: It should be sufficient to use the fastest liveness 505 // TODO: It should be sufficient to use the fastest liveness
478 // calculation, i.e. livenessLightweight(). However, for some 506 // calculation, i.e. livenessLightweight(). However, for some
479 // reason that slows down the rest of the translation. Investigate. 507 // reason that slows down the rest of the translation. Investigate.
480 Func->liveness(Liveness_Basic); 508 Func->liveness(Liveness_Basic);
481 if (Func->hasError()) 509 if (Func->hasError())
482 return; 510 return;
483 Func->dump("After x86 address mode opt"); 511 Func->dump("After x86 address mode opt");
484 512
485 doLoadOpt(); 513 // qining: disable constant blinding or pooling for load optimization
514 {
515 BoolFlagSaver B(RandomizationPoolingPaused, true);
516 doLoadOpt();
517 }
486 Func->genCode(); 518 Func->genCode();
487 if (Func->hasError()) 519 if (Func->hasError())
488 return; 520 return;
489 Func->dump("After x86 codegen"); 521 Func->dump("After x86 codegen");
490 522
491 // Register allocation. This requires instruction renumbering and 523 // Register allocation. This requires instruction renumbering and
492 // full liveness analysis. 524 // full liveness analysis.
493 Func->renumberInstructions(); 525 Func->renumberInstructions();
494 if (Func->hasError()) 526 if (Func->hasError())
495 return; 527 return;
496 Func->liveness(Liveness_Intervals); 528 Func->liveness(Liveness_Intervals);
497 if (Func->hasError()) 529 if (Func->hasError())
498 return; 530 return;
499 // Validate the live range computations. The expensive validation 531 // Validate the live range computations. The expensive validation
500 // call is deliberately only made when assertions are enabled. 532 // call is deliberately only made when assertions are enabled.
501 assert(Func->validateLiveness()); 533 assert(Func->validateLiveness());
502 // The post-codegen dump is done here, after liveness analysis and 534 // The post-codegen dump is done here, after liveness analysis and
503 // associated cleanup, to make the dump cleaner and more useful. 535 // associated cleanup, to make the dump cleaner and more useful.
504 Func->dump("After initial x8632 codegen"); 536 Func->dump("After initial x8632 codegen");
505 Func->getVMetadata()->init(VMK_All); 537 Func->getVMetadata()->init(VMK_All);
506 regAlloc(RAK_Global); 538 regAlloc(RAK_Global);
507 if (Func->hasError()) 539 if (Func->hasError())
508 return; 540 return;
509 Func->dump("After linear scan regalloc"); 541 Func->dump("After linear scan regalloc");
510 542
511 if (Ctx->getFlags().getPhiEdgeSplit()) { 543 if (Ctx->getFlags().getPhiEdgeSplit()) {
512 Func->advancedPhiLowering(); 544 // qining: In general we need to pause constant blinding or pooling
545 // during advanced phi lowering, unless the lowering assignment has a
546 // physical register for the Dest Variable
547 {
548 BoolFlagSaver B(RandomizationPoolingPaused, true);
549 Func->advancedPhiLowering();
550 }
513 Func->dump("After advanced Phi lowering"); 551 Func->dump("After advanced Phi lowering");
514 } 552 }
515 553
516 // Stack frame mapping. 554 // Stack frame mapping.
517 Func->genFrame(); 555 Func->genFrame();
518 if (Func->hasError()) 556 if (Func->hasError())
519 return; 557 return;
520 Func->dump("After stack frame mapping"); 558 Func->dump("After stack frame mapping");
521 559
522 Func->contractEmptyNodes(); 560 Func->contractEmptyNodes();
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 return RegNames[RegNum]; 793 return RegNames[RegNum];
756 } 794 }
757 } 795 }
758 796
759 void TargetX8632::emitVariable(const Variable *Var) const { 797 void TargetX8632::emitVariable(const Variable *Var) const {
760 Ostream &Str = Ctx->getStrEmit(); 798 Ostream &Str = Ctx->getStrEmit();
761 if (Var->hasReg()) { 799 if (Var->hasReg()) {
762 Str << "%" << getRegName(Var->getRegNum(), Var->getType()); 800 Str << "%" << getRegName(Var->getRegNum(), Var->getType());
763 return; 801 return;
764 } 802 }
765 if (Var->getWeight().isInf()) 803 if (Var->getWeight().isInf()) {
766 llvm_unreachable("Infinite-weight Variable has no register assigned"); 804 llvm_unreachable("Infinite-weight Variable has no register assigned");
805 }
767 int32_t Offset = Var->getStackOffset(); 806 int32_t Offset = Var->getStackOffset();
768 if (!hasFramePointer()) 807 if (!hasFramePointer())
769 Offset += getStackAdjustment(); 808 Offset += getStackAdjustment();
770 if (Offset) 809 if (Offset)
771 Str << Offset; 810 Str << Offset;
772 const Type FrameSPTy = IceType_i32; 811 const Type FrameSPTy = IceType_i32;
773 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")"; 812 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")";
774 } 813 }
775 814
776 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const { 815 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const {
777 if (Var->hasReg()) 816 if (Var->hasReg())
778 llvm_unreachable("Stack Variable has a register assigned"); 817 llvm_unreachable("Stack Variable has a register assigned");
779 if (Var->getWeight().isInf()) 818 if (Var->getWeight().isInf()) {
780 llvm_unreachable("Infinite-weight Variable has no register assigned"); 819 llvm_unreachable("Infinite-weight Variable has no register assigned");
820 }
781 int32_t Offset = Var->getStackOffset(); 821 int32_t Offset = Var->getStackOffset();
782 if (!hasFramePointer()) 822 if (!hasFramePointer())
783 Offset += getStackAdjustment(); 823 Offset += getStackAdjustment();
784 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset); 824 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset);
785 } 825 }
786 826
787 void TargetX8632::lowerArguments() { 827 void TargetX8632::lowerArguments() {
788 VarList &Args = Func->getArgs(); 828 VarList &Args = Func->getArgs();
789 // The first four arguments of vector type, regardless of their 829 // The first four arguments of vector type, regardless of their
790 // position relative to the other arguments in the argument list, are 830 // 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) { 1201 Operand *TargetX8632::loOperand(Operand *Operand) {
1162 assert(Operand->getType() == IceType_i64 || 1202 assert(Operand->getType() == IceType_i64 ||
1163 Operand->getType() == IceType_f64); 1203 Operand->getType() == IceType_f64);
1164 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1204 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1165 return Operand; 1205 return Operand;
1166 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1206 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1167 split64(Var); 1207 split64(Var);
1168 return Var->getLo(); 1208 return Var->getLo();
1169 } 1209 }
1170 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1210 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1171 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 1211 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
1212 Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue())));
1213 // check if we need to blind/pool the constant
1214 return randomizeOrPoolImmediate(ConstInt);
1172 } 1215 }
1173 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1216 if (OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(Operand)) {
1174 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 1217 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1175 Mem->getOffset(), Mem->getIndex(), 1218 Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
1176 Mem->getShift(), Mem->getSegmentRegister()); 1219 Mem->getShift(), Mem->getSegmentRegister());
1220 // Test if we should randomize or pool the offset, if so randomize it or
1221 // pool it then create mem operand with the blinded/pooled constant.
1222 // Otherwise, return the mem operand as ordinary mem operand.
1223 return randomizeOrPoolImmediate(MemOperand);
1177 } 1224 }
1178 llvm_unreachable("Unsupported operand type"); 1225 llvm_unreachable("Unsupported operand type");
1179 return nullptr; 1226 return nullptr;
1180 } 1227 }
1181 1228
1182 Operand *TargetX8632::hiOperand(Operand *Operand) { 1229 Operand *TargetX8632::hiOperand(Operand *Operand) {
1183 assert(Operand->getType() == IceType_i64 || 1230 assert(Operand->getType() == IceType_i64 ||
1184 Operand->getType() == IceType_f64); 1231 Operand->getType() == IceType_f64);
1185 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1232 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1186 return Operand; 1233 return Operand;
1187 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1234 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1188 split64(Var); 1235 split64(Var);
1189 return Var->getHi(); 1236 return Var->getHi();
1190 } 1237 }
1191 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1238 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1192 return Ctx->getConstantInt32( 1239 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
1193 static_cast<uint32_t>(Const->getValue() >> 32)); 1240 Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue() >> 32)));
1241 // check if we need to blind/pool the constant
1242 return randomizeOrPoolImmediate(ConstInt);
1194 } 1243 }
1195 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1244 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
1196 Constant *Offset = Mem->getOffset(); 1245 Constant *Offset = Mem->getOffset();
1197 if (Offset == nullptr) { 1246 if (Offset == nullptr) {
1198 Offset = Ctx->getConstantInt32(4); 1247 Offset = Ctx->getConstantInt32(4);
1199 } else if (ConstantInteger32 *IntOffset = 1248 } else if (ConstantInteger32 *IntOffset =
1200 llvm::dyn_cast<ConstantInteger32>(Offset)) { 1249 llvm::dyn_cast<ConstantInteger32>(Offset)) {
1201 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue()); 1250 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue());
1202 } else if (ConstantRelocatable *SymOffset = 1251 } else if (ConstantRelocatable *SymOffset =
1203 llvm::dyn_cast<ConstantRelocatable>(Offset)) { 1252 llvm::dyn_cast<ConstantRelocatable>(Offset)) {
1204 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4)); 1253 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4));
1205 Offset = 1254 Offset =
1206 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(), 1255 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
1207 SymOffset->getSuppressMangling()); 1256 SymOffset->getSuppressMangling());
1208 } 1257 }
1209 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, 1258 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1210 Mem->getIndex(), Mem->getShift(), 1259 Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
1211 Mem->getSegmentRegister()); 1260 Mem->getShift(), Mem->getSegmentRegister());
1261 // Test if the Offset is an eligible i32 constants for randomization and
1262 // pooling. Blind/pool it if it is. Otherwise return as oridinary mem
1263 // operand.
1264 return randomizeOrPoolImmediate(MemOperand);
1212 } 1265 }
1213 llvm_unreachable("Unsupported operand type"); 1266 llvm_unreachable("Unsupported operand type");
1214 return nullptr; 1267 return nullptr;
1215 } 1268 }
1216 1269
1217 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, 1270 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
1218 RegSetMask Exclude) const { 1271 RegSetMask Exclude) const {
1219 llvm::SmallBitVector Registers(RegX8632::Reg_NUM); 1272 llvm::SmallBitVector Registers(RegX8632::Reg_NUM);
1220 1273
1221 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 1274 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 // multiple of the required alignment at runtime. 1333 // multiple of the required alignment at runtime.
1281 Variable *T = makeReg(IceType_i32); 1334 Variable *T = makeReg(IceType_i32);
1282 _mov(T, TotalSize); 1335 _mov(T, TotalSize);
1283 _add(T, Ctx->getConstantInt32(Alignment - 1)); 1336 _add(T, Ctx->getConstantInt32(Alignment - 1));
1284 _and(T, Ctx->getConstantInt32(-Alignment)); 1337 _and(T, Ctx->getConstantInt32(-Alignment));
1285 _sub(esp, T); 1338 _sub(esp, T);
1286 } 1339 }
1287 _mov(Dest, esp); 1340 _mov(Dest, esp);
1288 } 1341 }
1289 1342
1343 // Strength-reduce scalar integer multiplication by a constant (for
1344 // i32 or narrower) for certain constants. The lea instruction can be
1345 // used to multiply by 3, 5, or 9, and the lsh instruction can be used
1346 // to multiply by powers of 2. These can be combined such that
1347 // e.g. multiplying by 100 can be done as 2 lea-based multiplies by 5,
1348 // combined with left-shifting by 2.
1349 bool TargetX8632::optimizeScalarMul(Variable *Dest, Operand *Src0,
1350 int32_t Src1) {
1351 // Disable this optimization for Om1 and O0, just to keep things
1352 // simple there.
1353 if (Ctx->getFlags().getOptLevel() < Opt_1)
1354 return false;
1355 Type Ty = Dest->getType();
1356 Variable *T = nullptr;
1357 if (Src1 == -1) {
1358 _mov(T, Src0);
1359 _neg(T);
1360 _mov(Dest, T);
1361 return true;
1362 }
1363 if (Src1 == 0) {
1364 _mov(Dest, Ctx->getConstantZero(Ty));
1365 return true;
1366 }
1367 if (Src1 == 1) {
1368 _mov(T, Src0);
1369 _mov(Dest, T);
1370 return true;
1371 }
1372 // Don't bother with the edge case where Src1 == MININT.
1373 if (Src1 == -Src1)
1374 return false;
1375 const bool Src1IsNegative = Src1 < 0;
1376 if (Src1IsNegative)
1377 Src1 = -Src1;
1378 uint32_t Count9 = 0;
1379 uint32_t Count5 = 0;
1380 uint32_t Count3 = 0;
1381 uint32_t Count2 = 0;
1382 uint32_t CountOps = 0;
1383 while (Src1 > 1) {
1384 if (Src1 % 9 == 0) {
1385 ++CountOps;
1386 ++Count9;
1387 Src1 /= 9;
1388 } else if (Src1 % 5 == 0) {
1389 ++CountOps;
1390 ++Count5;
1391 Src1 /= 5;
1392 } else if (Src1 % 3 == 0) {
1393 ++CountOps;
1394 ++Count3;
1395 Src1 /= 3;
1396 } else if (Src1 % 2 == 0) {
1397 if (Count2 == 0)
1398 ++CountOps;
1399 ++Count2;
1400 Src1 /= 2;
1401 } else {
1402 return false;
1403 }
1404 }
1405 // Lea optimization only works for i16 and i32 types, not i8.
1406 if (Ty != IceType_i16 && Ty != IceType_i32 && (Count3 || Count5 || Count9))
1407 return false;
1408 // Limit the number of lea/shl operations for a single multiply, to
1409 // a somewhat arbitrary choice of 3.
1410 const uint32_t MaxOpsForOptimizedMul = 3;
1411 if (CountOps > MaxOpsForOptimizedMul)
1412 return false;
1413 _mov(T, Src0);
1414 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1415 for (uint32_t i = 0; i < Count9; ++i) {
1416 const uint16_t Shift = 3; // log2(9-1)
1417 _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
1418 _set_dest_nonkillable();
1419 }
1420 for (uint32_t i = 0; i < Count5; ++i) {
1421 const uint16_t Shift = 2; // log2(5-1)
1422 _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
1423 _set_dest_nonkillable();
1424 }
1425 for (uint32_t i = 0; i < Count3; ++i) {
1426 const uint16_t Shift = 1; // log2(3-1)
1427 _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
1428 _set_dest_nonkillable();
1429 }
1430 if (Count2) {
1431 _shl(T, Ctx->getConstantInt(Ty, Count2));
1432 }
1433 if (Src1IsNegative)
1434 _neg(T);
1435 _mov(Dest, T);
1436 return true;
1437 }
qining 2015/06/17 04:28:55 I believe this new block comes from rebasing.
1438
1290 void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) { 1439 void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
1291 Variable *Dest = Inst->getDest(); 1440 Variable *Dest = Inst->getDest();
1292 Operand *Src0 = legalize(Inst->getSrc(0)); 1441 Operand *Src0 = legalize(Inst->getSrc(0));
1293 Operand *Src1 = legalize(Inst->getSrc(1)); 1442 Operand *Src1 = legalize(Inst->getSrc(1));
1294 if (Inst->isCommutative()) { 1443 if (Inst->isCommutative()) {
1295 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) 1444 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1))
1296 std::swap(Src0, Src1); 1445 std::swap(Src0, Src1);
1446 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1))
1447 std::swap(Src0, Src1);
1297 } 1448 }
1298 if (Dest->getType() == IceType_i64) { 1449 if (Dest->getType() == IceType_i64) {
1450 switch (Inst->getOp()) {
1451 case InstArithmetic::Udiv: {
1452 const SizeT MaxSrcs = 2;
1453 InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
1454 Call->addArg(Inst->getSrc(0));
1455 Call->addArg(Inst->getSrc(1));
1456 lowerCall(Call);
1457 return;
1458 }
1459 case InstArithmetic::Sdiv: {
1460 const SizeT MaxSrcs = 2;
1461 InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
1462 Call->addArg(Inst->getSrc(0));
1463 Call->addArg(Inst->getSrc(1));
1464 lowerCall(Call);
1465 return;
1466 }
1467 case InstArithmetic::Urem: {
1468 const SizeT MaxSrcs = 2;
1469 InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
1470 Call->addArg(Inst->getSrc(0));
1471 Call->addArg(Inst->getSrc(1));
1472 lowerCall(Call);
1473 return;
1474 }
1475 case InstArithmetic::Srem: {
1476 const SizeT MaxSrcs = 2;
1477 InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
1478 Call->addArg(Inst->getSrc(0));
1479 Call->addArg(Inst->getSrc(1));
1480 lowerCall(Call);
1481 return;
1482 }
1483 default:
1484 break;
1485 }
1486
qining 2015/06/17 04:28:55 For the operations using helper calls, we should n
1299 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1487 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1300 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1488 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1301 Operand *Src0Lo = loOperand(Src0); 1489 Operand *Src0Lo = loOperand(Src0);
1302 Operand *Src0Hi = hiOperand(Src0); 1490 Operand *Src0Hi = hiOperand(Src0);
1303 Operand *Src1Lo = loOperand(Src1); 1491 Operand *Src1Lo = loOperand(Src1);
1304 Operand *Src1Hi = hiOperand(Src1); 1492 Operand *Src1Hi = hiOperand(Src1);
1305 Variable *T_Lo = nullptr, *T_Hi = nullptr; 1493 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1306 switch (Inst->getOp()) { 1494 switch (Inst->getOp()) {
1307 case InstArithmetic::_num: 1495 case InstArithmetic::_num:
1308 llvm_unreachable("Unknown arithmetic operator"); 1496 llvm_unreachable("Unknown arithmetic operator");
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 // T_2 and T_3 are being assigned again because of the 1666 // T_2 and T_3 are being assigned again because of the
1479 // intra-block control flow, so T_2 needs the _mov_nonkillable 1667 // intra-block control flow, so T_2 needs the _mov_nonkillable
1480 // variant to avoid liveness problems. T_3 doesn't need special 1668 // variant to avoid liveness problems. T_3 doesn't need special
1481 // treatment because it is reassigned via _sar instead of _mov. 1669 // treatment because it is reassigned via _sar instead of _mov.
1482 _mov_nonkillable(T_2, T_3); 1670 _mov_nonkillable(T_2, T_3);
1483 _sar(T_3, SignExtend); 1671 _sar(T_3, SignExtend);
1484 Context.insert(Label); 1672 Context.insert(Label);
1485 _mov(DestLo, T_2); 1673 _mov(DestLo, T_2);
1486 _mov(DestHi, T_3); 1674 _mov(DestHi, T_3);
1487 } break; 1675 } break;
1488 case InstArithmetic::Udiv: {
1489 const SizeT MaxSrcs = 2;
1490 InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
1491 Call->addArg(Inst->getSrc(0));
1492 Call->addArg(Inst->getSrc(1));
1493 lowerCall(Call);
1494 } break;
1495 case InstArithmetic::Sdiv: {
1496 const SizeT MaxSrcs = 2;
1497 InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
1498 Call->addArg(Inst->getSrc(0));
1499 Call->addArg(Inst->getSrc(1));
1500 lowerCall(Call);
1501 } break;
1502 case InstArithmetic::Urem: {
1503 const SizeT MaxSrcs = 2;
1504 InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
1505 Call->addArg(Inst->getSrc(0));
1506 Call->addArg(Inst->getSrc(1));
1507 lowerCall(Call);
1508 } break;
1509 case InstArithmetic::Srem: {
1510 const SizeT MaxSrcs = 2;
1511 InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
1512 Call->addArg(Inst->getSrc(0));
1513 Call->addArg(Inst->getSrc(1));
1514 lowerCall(Call);
1515 } break;
1516 case InstArithmetic::Fadd: 1676 case InstArithmetic::Fadd:
1517 case InstArithmetic::Fsub: 1677 case InstArithmetic::Fsub:
1518 case InstArithmetic::Fmul: 1678 case InstArithmetic::Fmul:
1519 case InstArithmetic::Fdiv: 1679 case InstArithmetic::Fdiv:
1520 case InstArithmetic::Frem: 1680 case InstArithmetic::Frem:
1521 llvm_unreachable("FP instruction with i64 type"); 1681 llvm_unreachable("FP instruction with i64 type");
1522 break; 1682 break;
1683 default:
1684 llvm_unreachable("Unknown instruction with i64 type");
1685 break;
1523 } 1686 }
1524 } else if (isVectorType(Dest->getType())) { 1687 return;
1688 }
1689 if (isVectorType(Dest->getType())) {
1525 // TODO: Trap on integer divide and integer modulo by zero. 1690 // TODO: Trap on integer divide and integer modulo by zero.
1526 // See: https://code.google.com/p/nativeclient/issues/detail?id=3899 1691 // See: https://code.google.com/p/nativeclient/issues/detail?id=3899
1527 if (llvm::isa<OperandX8632Mem>(Src1)) 1692 if (llvm::isa<OperandX8632Mem>(Src1))
1528 Src1 = legalizeToVar(Src1); 1693 Src1 = legalizeToVar(Src1);
1529 switch (Inst->getOp()) { 1694 switch (Inst->getOp()) {
1530 case InstArithmetic::_num: 1695 case InstArithmetic::_num:
1531 llvm_unreachable("Unknown arithmetic operator"); 1696 llvm_unreachable("Unknown arithmetic operator");
1532 break; 1697 break;
1533 case InstArithmetic::Add: { 1698 case InstArithmetic::Add: {
1534 Variable *T = makeReg(Dest->getType()); 1699 Variable *T = makeReg(Dest->getType());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 case InstArithmetic::Fdiv: { 1808 case InstArithmetic::Fdiv: {
1644 Variable *T = makeReg(Dest->getType()); 1809 Variable *T = makeReg(Dest->getType());
1645 _movp(T, Src0); 1810 _movp(T, Src0);
1646 _divps(T, Src1); 1811 _divps(T, Src1);
1647 _movp(Dest, T); 1812 _movp(Dest, T);
1648 } break; 1813 } break;
1649 case InstArithmetic::Frem: 1814 case InstArithmetic::Frem:
1650 scalarizeArithmetic(Inst->getOp(), Dest, Src0, Src1); 1815 scalarizeArithmetic(Inst->getOp(), Dest, Src0, Src1);
1651 break; 1816 break;
1652 } 1817 }
1653 } else { // Dest->getType() is non-i64 scalar 1818 return;
1654 Variable *T_edx = nullptr; 1819 }
1655 Variable *T = nullptr; 1820 Variable *T_edx = nullptr;
1656 switch (Inst->getOp()) { 1821 Variable *T = nullptr;
1657 case InstArithmetic::_num: 1822 switch (Inst->getOp()) {
1658 llvm_unreachable("Unknown arithmetic operator"); 1823 case InstArithmetic::_num:
1659 break; 1824 llvm_unreachable("Unknown arithmetic operator");
1660 case InstArithmetic::Add: 1825 break;
1826 case InstArithmetic::Add:
1827 _mov(T, Src0);
1828 _add(T, Src1);
1829 _mov(Dest, T);
1830 break;
1831 case InstArithmetic::And:
1832 _mov(T, Src0);
1833 _and(T, Src1);
1834 _mov(Dest, T);
1835 break;
1836 case InstArithmetic::Or:
1837 _mov(T, Src0);
1838 _or(T, Src1);
1839 _mov(Dest, T);
1840 break;
1841 case InstArithmetic::Xor:
1842 _mov(T, Src0);
1843 _xor(T, Src1);
1844 _mov(Dest, T);
1845 break;
1846 case InstArithmetic::Sub:
1847 _mov(T, Src0);
1848 _sub(T, Src1);
1849 _mov(Dest, T);
1850 break;
1851 case InstArithmetic::Mul:
1852 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
1853 if (optimizeScalarMul(Dest, Src0, C->getValue()))
1854 return;
1855 }
1856 // The 8-bit version of imul only allows the form "imul r/m8"
1857 // where T must be in eax.
1858 if (isByteSizedArithType(Dest->getType())) {
1859 _mov(T, Src0, RegX8632::Reg_eax);
1860 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1861 } else {
1661 _mov(T, Src0); 1862 _mov(T, Src0);
1662 _add(T, Src1); 1863 }
1663 _mov(Dest, T); 1864 _imul(T, Src1);
1664 break; 1865 _mov(Dest, T);
1665 case InstArithmetic::And: 1866 break;
1666 _mov(T, Src0); 1867 case InstArithmetic::Shl:
1667 _and(T, Src1); 1868 _mov(T, Src0);
1668 _mov(Dest, T); 1869 if (!llvm::isa<Constant>(Src1))
1669 break; 1870 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx);
1670 case InstArithmetic::Or: 1871 _shl(T, Src1);
1671 _mov(T, Src0); 1872 _mov(Dest, T);
1672 _or(T, Src1); 1873 break;
1673 _mov(Dest, T); 1874 case InstArithmetic::Lshr:
1674 break; 1875 _mov(T, Src0);
1675 case InstArithmetic::Xor: 1876 if (!llvm::isa<Constant>(Src1))
1676 _mov(T, Src0); 1877 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx);
1677 _xor(T, Src1); 1878 _shr(T, Src1);
1678 _mov(Dest, T); 1879 _mov(Dest, T);
1679 break; 1880 break;
1680 case InstArithmetic::Sub: 1881 case InstArithmetic::Ashr:
1681 _mov(T, Src0); 1882 _mov(T, Src0);
1682 _sub(T, Src1); 1883 if (!llvm::isa<Constant>(Src1))
1683 _mov(Dest, T); 1884 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx);
1684 break; 1885 _sar(T, Src1);
1685 case InstArithmetic::Mul: 1886 _mov(Dest, T);
1686 // TODO: Optimize for llvm::isa<Constant>(Src1) 1887 break;
1687 // TODO: Strength-reduce multiplications by a constant, 1888 case InstArithmetic::Udiv:
1688 // particularly -1 and powers of 2. Advanced: use lea to 1889 // div and idiv are the few arithmetic operators that do not allow
1689 // multiply by 3, 5, 9. 1890 // immediates as the operand.
1690 // 1891 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1691 // The 8-bit version of imul only allows the form "imul r/m8" 1892 if (isByteSizedArithType(Dest->getType())) {
1692 // where T must be in eax. 1893 Variable *T_ah = nullptr;
1693 if (isByteSizedArithType(Dest->getType())) { 1894 Constant *Zero = Ctx->getConstantZero(IceType_i8);
1694 _mov(T, Src0, RegX8632::Reg_eax); 1895 _mov(T, Src0, RegX8632::Reg_eax);
1695 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1896 _mov(T_ah, Zero, RegX8632::Reg_ah);
1696 } else { 1897 _div(T, Src1, T_ah);
1697 _mov(T, Src0); 1898 _mov(Dest, T);
1899 } else {
1900 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1901 _mov(T, Src0, RegX8632::Reg_eax);
1902 _mov(T_edx, Zero, RegX8632::Reg_edx);
1903 _div(T, Src1, T_edx);
1904 _mov(Dest, T);
1905 }
1906 break;
1907 case InstArithmetic::Sdiv:
1908 // TODO(stichnot): Enable this after doing better performance
1909 // and cross testing.
1910 if (false && Ctx->getFlags().getOptLevel() >= Opt_1) {
1911 // Optimize division by constant power of 2, but not for Om1
1912 // or O0, just to keep things simple there.
1913 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
1914 int32_t Divisor = C->getValue();
1915 uint32_t UDivisor = static_cast<uint32_t>(Divisor);
1916 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) {
1917 uint32_t LogDiv = llvm::Log2_32(UDivisor);
1918 Type Ty = Dest->getType();
1919 // LLVM does the following for dest=src/(1<<log):
1920 // t=src
1921 // sar t,typewidth-1 // -1 if src is negative, 0 if not
1922 // shr t,typewidth-log
1923 // add t,src
1924 // sar t,log
1925 // dest=t
1926 uint32_t TypeWidth = X86_CHAR_BIT * typeWidthInBytes(Ty);
1927 _mov(T, Src0);
1928 // If for some reason we are dividing by 1, just treat it
1929 // like an assignment.
1930 if (LogDiv > 0) {
1931 // The initial sar is unnecessary when dividing by 2.
1932 if (LogDiv > 1)
1933 _sar(T, Ctx->getConstantInt(Ty, TypeWidth - 1));
1934 _shr(T, Ctx->getConstantInt(Ty, TypeWidth - LogDiv));
1935 _add(T, Src0);
1936 _sar(T, Ctx->getConstantInt(Ty, LogDiv));
1937 }
1938 _mov(Dest, T);
1939 return;
1940 }
1698 } 1941 }
1699 _imul(T, Src1); 1942 }
1700 _mov(Dest, T); 1943 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1701 break; 1944 if (isByteSizedArithType(Dest->getType())) {
1702 case InstArithmetic::Shl: 1945 _mov(T, Src0, RegX8632::Reg_eax);
1703 _mov(T, Src0); 1946 _cbwdq(T, T);
1704 if (!llvm::isa<Constant>(Src1)) 1947 _idiv(T, Src1, T);
1705 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); 1948 _mov(Dest, T);
1706 _shl(T, Src1); 1949 } else {
1707 _mov(Dest, T); 1950 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
1708 break; 1951 _mov(T, Src0, RegX8632::Reg_eax);
1709 case InstArithmetic::Lshr: 1952 _cbwdq(T_edx, T);
1710 _mov(T, Src0); 1953 _idiv(T, Src1, T_edx);
1711 if (!llvm::isa<Constant>(Src1)) 1954 _mov(Dest, T);
1712 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); 1955 }
1713 _shr(T, Src1); 1956 break;
1714 _mov(Dest, T); 1957 case InstArithmetic::Urem:
1715 break; 1958 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1716 case InstArithmetic::Ashr: 1959 if (isByteSizedArithType(Dest->getType())) {
1717 _mov(T, Src0); 1960 Variable *T_ah = nullptr;
1718 if (!llvm::isa<Constant>(Src1)) 1961 Constant *Zero = Ctx->getConstantZero(IceType_i8);
1719 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); 1962 _mov(T, Src0, RegX8632::Reg_eax);
1720 _sar(T, Src1); 1963 _mov(T_ah, Zero, RegX8632::Reg_ah);
1721 _mov(Dest, T); 1964 _div(T_ah, Src1, T);
1722 break; 1965 _mov(Dest, T_ah);
1723 case InstArithmetic::Udiv: 1966 } else {
1724 // div and idiv are the few arithmetic operators that do not allow 1967 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1725 // immediates as the operand. 1968 _mov(T_edx, Zero, RegX8632::Reg_edx);
1726 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1969 _mov(T, Src0, RegX8632::Reg_eax);
1727 if (isByteSizedArithType(Dest->getType())) { 1970 _div(T_edx, Src1, T);
1728 Variable *T_ah = nullptr; 1971 _mov(Dest, T_edx);
1729 Constant *Zero = Ctx->getConstantZero(IceType_i8); 1972 }
1730 _mov(T, Src0, RegX8632::Reg_eax); 1973 break;
1731 _mov(T_ah, Zero, RegX8632::Reg_ah); 1974 case InstArithmetic::Srem:
1732 _div(T, Src1, T_ah); 1975 // TODO(stichnot): Enable this after doing better performance
1733 _mov(Dest, T); 1976 // and cross testing.
1734 } else { 1977 if (false && Ctx->getFlags().getOptLevel() >= Opt_1) {
1735 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1978 // Optimize mod by constant power of 2, but not for Om1 or O0,
1736 _mov(T, Src0, RegX8632::Reg_eax); 1979 // just to keep things simple there.
1737 _mov(T_edx, Zero, RegX8632::Reg_edx); 1980 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
1738 _div(T, Src1, T_edx); 1981 int32_t Divisor = C->getValue();
1739 _mov(Dest, T); 1982 uint32_t UDivisor = static_cast<uint32_t>(Divisor);
1983 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) {
1984 uint32_t LogDiv = llvm::Log2_32(UDivisor);
1985 Type Ty = Dest->getType();
1986 // LLVM does the following for dest=src%(1<<log):
1987 // t=src
1988 // sar t,typewidth-1 // -1 if src is negative, 0 if not
1989 // shr t,typewidth-log
1990 // add t,src
1991 // and t, -(1<<log)
1992 // sub t,src
1993 // neg t
1994 // dest=t
1995 uint32_t TypeWidth = X86_CHAR_BIT * typeWidthInBytes(Ty);
1996 // If for some reason we are dividing by 1, just assign 0.
1997 if (LogDiv == 0) {
1998 _mov(Dest, Ctx->getConstantZero(Ty));
1999 return;
2000 }
2001 _mov(T, Src0);
2002 // The initial sar is unnecessary when dividing by 2.
2003 if (LogDiv > 1)
2004 _sar(T, Ctx->getConstantInt(Ty, TypeWidth - 1));
2005 _shr(T, Ctx->getConstantInt(Ty, TypeWidth - LogDiv));
2006 _add(T, Src0);
2007 _and(T, Ctx->getConstantInt(Ty, -(1 << LogDiv)));
2008 _sub(T, Src0);
2009 _neg(T);
2010 _mov(Dest, T);
2011 return;
2012 }
1740 } 2013 }
1741 break; 2014 }
1742 case InstArithmetic::Sdiv: 2015 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1743 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2016 if (isByteSizedArithType(Dest->getType())) {
1744 if (isByteSizedArithType(Dest->getType())) { 2017 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah);
1745 _mov(T, Src0, RegX8632::Reg_eax); 2018 _mov(T, Src0, RegX8632::Reg_eax);
1746 _cbwdq(T, T); 2019 _cbwdq(T, T);
1747 _idiv(T, Src1, T); 2020 Context.insert(InstFakeDef::create(Func, T_ah));
1748 _mov(Dest, T); 2021 _idiv(T_ah, Src1, T);
1749 } else { 2022 _mov(Dest, T_ah);
1750 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); 2023 } else {
1751 _mov(T, Src0, RegX8632::Reg_eax); 2024 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
1752 _cbwdq(T_edx, T); 2025 _mov(T, Src0, RegX8632::Reg_eax);
1753 _idiv(T, Src1, T_edx); 2026 _cbwdq(T_edx, T);
1754 _mov(Dest, T); 2027 _idiv(T_edx, Src1, T);
1755 } 2028 _mov(Dest, T_edx);
1756 break; 2029 }
1757 case InstArithmetic::Urem: 2030 break;
1758 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2031 case InstArithmetic::Fadd:
1759 if (isByteSizedArithType(Dest->getType())) { 2032 _mov(T, Src0);
1760 Variable *T_ah = nullptr; 2033 _addss(T, Src1);
1761 Constant *Zero = Ctx->getConstantZero(IceType_i8); 2034 _mov(Dest, T);
1762 _mov(T, Src0, RegX8632::Reg_eax); 2035 break;
1763 _mov(T_ah, Zero, RegX8632::Reg_ah); 2036 case InstArithmetic::Fsub:
1764 _div(T_ah, Src1, T); 2037 _mov(T, Src0);
1765 _mov(Dest, T_ah); 2038 _subss(T, Src1);
1766 } else { 2039 _mov(Dest, T);
1767 Constant *Zero = Ctx->getConstantZero(IceType_i32); 2040 break;
1768 _mov(T_edx, Zero, RegX8632::Reg_edx); 2041 case InstArithmetic::Fmul:
1769 _mov(T, Src0, RegX8632::Reg_eax); 2042 _mov(T, Src0);
1770 _div(T_edx, Src1, T); 2043 _mulss(T, Src1);
1771 _mov(Dest, T_edx); 2044 _mov(Dest, T);
1772 } 2045 break;
1773 break; 2046 case InstArithmetic::Fdiv:
1774 case InstArithmetic::Srem: 2047 _mov(T, Src0);
1775 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2048 _divss(T, Src1);
1776 if (isByteSizedArithType(Dest->getType())) { 2049 _mov(Dest, T);
1777 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah); 2050 break;
1778 _mov(T, Src0, RegX8632::Reg_eax); 2051 case InstArithmetic::Frem: {
1779 _cbwdq(T, T); 2052 const SizeT MaxSrcs = 2;
1780 Context.insert(InstFakeDef::create(Func, T_ah)); 2053 Type Ty = Dest->getType();
1781 _idiv(T_ah, Src1, T); 2054 InstCall *Call = makeHelperCall(
1782 _mov(Dest, T_ah); 2055 isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64, Dest, MaxSrcs);
1783 } else { 2056 Call->addArg(Src0);
1784 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); 2057 Call->addArg(Src1);
1785 _mov(T, Src0, RegX8632::Reg_eax); 2058 return lowerCall(Call);
1786 _cbwdq(T_edx, T); 2059 }
1787 _idiv(T_edx, Src1, T);
1788 _mov(Dest, T_edx);
1789 }
1790 break;
1791 case InstArithmetic::Fadd:
1792 _mov(T, Src0);
1793 _addss(T, Src1);
1794 _mov(Dest, T);
1795 break;
1796 case InstArithmetic::Fsub:
1797 _mov(T, Src0);
1798 _subss(T, Src1);
1799 _mov(Dest, T);
1800 break;
1801 case InstArithmetic::Fmul:
1802 _mov(T, Src0);
1803 _mulss(T, Src1);
1804 _mov(Dest, T);
1805 break;
1806 case InstArithmetic::Fdiv:
1807 _mov(T, Src0);
1808 _divss(T, Src1);
1809 _mov(Dest, T);
1810 break;
1811 case InstArithmetic::Frem: {
1812 const SizeT MaxSrcs = 2;
1813 Type Ty = Dest->getType();
1814 InstCall *Call =
1815 makeHelperCall(isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64,
1816 Dest, MaxSrcs);
1817 Call->addArg(Src0);
1818 Call->addArg(Src1);
1819 return lowerCall(Call);
1820 } break;
1821 }
1822 } 2060 }
1823 } 2061 }
1824 2062
1825 void TargetX8632::lowerAssign(const InstAssign *Inst) { 2063 void TargetX8632::lowerAssign(const InstAssign *Inst) {
1826 Variable *Dest = Inst->getDest(); 2064 Variable *Dest = Inst->getDest();
1827 Operand *Src0 = Inst->getSrc(0); 2065 Operand *Src0 = Inst->getSrc(0);
1828 assert(Dest->getType() == Src0->getType()); 2066 assert(Dest->getType() == Src0->getType());
1829 if (Dest->getType() == IceType_i64) { 2067 if (Dest->getType() == IceType_i64) {
1830 Src0 = legalize(Src0); 2068 Src0 = legalize(Src0);
1831 Operand *Src0Lo = loOperand(Src0); 2069 Operand *Src0Lo = loOperand(Src0);
1832 Operand *Src0Hi = hiOperand(Src0); 2070 Operand *Src0Hi = hiOperand(Src0);
1833 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2071 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1834 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2072 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1835 Variable *T_Lo = nullptr, *T_Hi = nullptr; 2073 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1836 _mov(T_Lo, Src0Lo); 2074 _mov(T_Lo, Src0Lo);
1837 _mov(DestLo, T_Lo); 2075 _mov(DestLo, T_Lo);
1838 _mov(T_Hi, Src0Hi); 2076 _mov(T_Hi, Src0Hi);
1839 _mov(DestHi, T_Hi); 2077 _mov(DestHi, T_Hi);
1840 } else { 2078 } else {
1841 Operand *RI; 2079 Operand *RI;
1842 if (Dest->hasReg()) 2080 if (Dest->hasReg()) {
1843 // If Dest already has a physical register, then legalize the 2081 // If Dest already has a physical register, then legalize the
1844 // Src operand into a Variable with the same register 2082 // Src operand into a Variable with the same register
1845 // assignment. This is mostly a workaround for advanced phi 2083 // assignment. This is mostly a workaround for advanced phi
1846 // lowering's ad-hoc register allocation which assumes no 2084 // lowering's ad-hoc register allocation which assumes no
1847 // register allocation is needed when at least one of the 2085 // register allocation is needed when at least one of the
1848 // operands is non-memory. 2086 // operands is non-memory.
1849 RI = legalize(Src0, Legal_Reg, Dest->getRegNum()); 2087
1850 else 2088 // qining: if we have a physical register for the dest variable,
2089 // we can enable our constant blinding or pooling again. Note
2090 // this is only for advancedPhiLowering(), the flag flip should
2091 // leave no other side effect.
2092 {
2093 BoolFlagSaver B(RandomizationPoolingPaused, false);
2094 RI = legalize(Src0, Legal_Reg, Dest->getRegNum());
2095 }
2096 } else {
1851 // If Dest could be a stack operand, then RI must be a physical 2097 // If Dest could be a stack operand, then RI must be a physical
1852 // register or a scalar integer immediate. 2098 // register or a scalar integer immediate.
1853 RI = legalize(Src0, Legal_Reg | Legal_Imm); 2099 RI = legalize(Src0, Legal_Reg | Legal_Imm);
2100 }
1854 if (isVectorType(Dest->getType())) 2101 if (isVectorType(Dest->getType()))
1855 _movp(Dest, RI); 2102 _movp(Dest, RI);
1856 else 2103 else
1857 _mov(Dest, RI); 2104 _mov(Dest, RI);
1858 } 2105 }
1859 } 2106 }
1860 2107
1861 void TargetX8632::lowerBr(const InstBr *Inst) { 2108 void TargetX8632::lowerBr(const InstBr *Inst) {
1862 if (Inst->isUnconditional()) { 2109 if (Inst->isUnconditional()) {
1863 _br(Inst->getTargetUnconditional()); 2110 _br(Inst->getTargetUnconditional());
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 Context.insert( 3359 Context.insert(
3113 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); 3360 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
3114 return; 3361 return;
3115 } 3362 }
3116 case Intrinsics::AtomicRMW: 3363 case Intrinsics::AtomicRMW:
3117 if (!Intrinsics::isMemoryOrderValid( 3364 if (!Intrinsics::isMemoryOrderValid(
3118 ID, getConstantMemoryOrder(Instr->getArg(3)))) { 3365 ID, getConstantMemoryOrder(Instr->getArg(3)))) {
3119 Func->setError("Unexpected memory ordering for AtomicRMW"); 3366 Func->setError("Unexpected memory ordering for AtomicRMW");
3120 return; 3367 return;
3121 } 3368 }
3122 lowerAtomicRMW(Instr->getDest(), 3369 lowerAtomicRMW(
3123 static_cast<uint32_t>(llvm::cast<ConstantInteger32>( 3370 Instr->getDest(),
3124 Instr->getArg(0))->getValue()), 3371 static_cast<uint32_t>(
3125 Instr->getArg(1), Instr->getArg(2)); 3372 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()),
3373 Instr->getArg(1), Instr->getArg(2));
3126 return; 3374 return;
3127 case Intrinsics::AtomicStore: { 3375 case Intrinsics::AtomicStore: {
3128 if (!Intrinsics::isMemoryOrderValid( 3376 if (!Intrinsics::isMemoryOrderValid(
3129 ID, getConstantMemoryOrder(Instr->getArg(2)))) { 3377 ID, getConstantMemoryOrder(Instr->getArg(2)))) {
3130 Func->setError("Unexpected memory ordering for AtomicStore"); 3378 Func->setError("Unexpected memory ordering for AtomicStore");
3131 return; 3379 return;
3132 } 3380 }
3133 // We require the memory address to be naturally aligned. 3381 // We require the memory address to be naturally aligned.
3134 // Given that is the case, then normal stores are atomic. 3382 // Given that is the case, then normal stores are atomic.
3135 // Add a fence after the store to make it visible. 3383 // Add a fence after the store to make it visible.
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4318 } 4566 }
4319 } 4567 }
4320 4568
4321 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { _ud2(); } 4569 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { _ud2(); }
4322 4570
4323 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to 4571 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
4324 // preserve integrity of liveness analysis. Undef values are also 4572 // preserve integrity of liveness analysis. Undef values are also
4325 // turned into zeroes, since loOperand() and hiOperand() don't expect 4573 // turned into zeroes, since loOperand() and hiOperand() don't expect
4326 // Undef input. 4574 // Undef input.
4327 void TargetX8632::prelowerPhis() { 4575 void TargetX8632::prelowerPhis() {
4576 // Pause constant blinding or pooling, blinding or pooling will be done later
4577 // during phi lowering assignments
4578 BoolFlagSaver B(RandomizationPoolingPaused, true);
4579
4328 CfgNode *Node = Context.getNode(); 4580 CfgNode *Node = Context.getNode();
4329 for (Inst &I : Node->getPhis()) { 4581 for (Inst &I : Node->getPhis()) {
4330 auto Phi = llvm::dyn_cast<InstPhi>(&I); 4582 auto Phi = llvm::dyn_cast<InstPhi>(&I);
4331 if (Phi->isDeleted()) 4583 if (Phi->isDeleted())
4332 continue; 4584 continue;
4333 Variable *Dest = Phi->getDest(); 4585 Variable *Dest = Phi->getDest();
4334 if (Dest->getType() == IceType_i64) { 4586 if (Dest->getType() == IceType_i64) {
4335 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 4587 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
4336 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 4588 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
4337 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo); 4589 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4417 // assignment, add Dest to the set of available registers, and 4669 // assignment, add Dest to the set of available registers, and
4418 // remove Src from the set of available registers. Iteration is 4670 // remove Src from the set of available registers. Iteration is
4419 // done backwards to enable incremental updates of the available 4671 // done backwards to enable incremental updates of the available
4420 // register set, and the lowered instruction numbers may be out of 4672 // register set, and the lowered instruction numbers may be out of
4421 // order, but that can be worked around by renumbering the block 4673 // order, but that can be worked around by renumbering the block
4422 // afterwards if necessary. 4674 // afterwards if necessary.
4423 for (const Inst &I : reverse_range(Assignments)) { 4675 for (const Inst &I : reverse_range(Assignments)) {
4424 Context.rewind(); 4676 Context.rewind();
4425 auto Assign = llvm::dyn_cast<InstAssign>(&I); 4677 auto Assign = llvm::dyn_cast<InstAssign>(&I);
4426 Variable *Dest = Assign->getDest(); 4678 Variable *Dest = Assign->getDest();
4679
4680 // qining: Here is an ugly hack for phi.ll test.
4681 // In function test_split_undef_int_vec, the advanced phi
4682 // lowering process will find an assignment of undefined
4683 // vector. This vector, as the Src here, will crash if it
4684 // go through legalize(). legalize() will create new variable
4685 // with makeVectorOfZeros(), but this new variable will be
4686 // assigned a stack slot. This will fail the assertion in
4687 // IceInstX8632.cpp:789, as XmmEmitterRegOp() complain:
4688 // Var->hasReg() fails. Note this failure is irrelevant to
4689 // randomization or pooling of constants.
4690 // So, we do not call legalize() to add pool label for the
4691 // src operands of phi assignment instructions.
4692 // Instead, we manually add pool label for constant float and
4693 // constant double values here.
4694 // Note going through legalize() does not affect the testing
4695 // results of SPEC2K and xtests.
4696 // Operand *Src = legalize(Assign->getSrc(0));
4427 Operand *Src = Assign->getSrc(0); 4697 Operand *Src = Assign->getSrc(0);
4698 if (llvm::isa<ConstantFloat>(Src) || llvm::isa<ConstantDouble>(Src)) {
4699 Variable *Base = nullptr;
4700 std::string Buffer;
4701 llvm::raw_string_ostream StrBuf(Buffer);
4702 llvm::cast<Constant>(Src)->emitPoolLabel(StrBuf);
4703 llvm::cast<Constant>(Src)->shouldBePooled = true;
4704 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
4705 Src = OperandX8632Mem::create(Func, Src->getType(), Base, Offset);
4706 }
4707
4428 Variable *SrcVar = llvm::dyn_cast<Variable>(Src); 4708 Variable *SrcVar = llvm::dyn_cast<Variable>(Src);
4429 // Use normal assignment lowering, except lower mem=mem specially 4709 // Use normal assignment lowering, except lower mem=mem specially
4430 // so we can register-allocate at the same time. 4710 // so we can register-allocate at the same time.
4431 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) { 4711 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) {
4432 lowerAssign(Assign); 4712 lowerAssign(Assign);
4433 } else { 4713 } else {
4434 assert(Dest->getType() == Src->getType()); 4714 assert(Dest->getType() == Src->getType());
4435 const llvm::SmallBitVector &RegsForType = 4715 const llvm::SmallBitVector &RegsForType =
4436 getRegisterSetForType(Dest->getType()); 4716 getRegisterSetForType(Dest->getType());
4437 llvm::SmallBitVector AvailRegsForType = RegsForType & Available; 4717 llvm::SmallBitVector AvailRegsForType = RegsForType & Available;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4607 Variable *Index = Mem->getIndex(); 4887 Variable *Index = Mem->getIndex();
4608 Variable *RegBase = nullptr; 4888 Variable *RegBase = nullptr;
4609 Variable *RegIndex = nullptr; 4889 Variable *RegIndex = nullptr;
4610 if (Base) { 4890 if (Base) {
4611 RegBase = legalizeToVar(Base); 4891 RegBase = legalizeToVar(Base);
4612 } 4892 }
4613 if (Index) { 4893 if (Index) {
4614 RegIndex = legalizeToVar(Index); 4894 RegIndex = legalizeToVar(Index);
4615 } 4895 }
4616 if (Base != RegBase || Index != RegIndex) { 4896 if (Base != RegBase || Index != RegIndex) {
4617 From = 4897 Mem =
4618 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex, 4898 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
4619 Mem->getShift(), Mem->getSegmentRegister()); 4899 Mem->getShift(), Mem->getSegmentRegister());
4620 } 4900 }
4621 4901
4902 // qining: For all Memory Operands, we do randomization/pooling here
4903 From = randomizeOrPoolImmediate(Mem);
4904
4622 if (!(Allowed & Legal_Mem)) { 4905 if (!(Allowed & Legal_Mem)) {
4623 From = copyToReg(From, RegNum); 4906 From = copyToReg(From, RegNum);
4624 } 4907 }
4625 return From; 4908 return From;
4626 } 4909 }
4627 if (llvm::isa<Constant>(From)) { 4910 if (llvm::isa<Constant>(From)) {
4628 if (llvm::isa<ConstantUndef>(From)) { 4911 if (llvm::isa<ConstantUndef>(From)) {
4629 // Lower undefs to zero. Another option is to lower undefs to an 4912 // Lower undefs to zero. Another option is to lower undefs to an
4630 // uninitialized register; however, using an uninitialized register 4913 // uninitialized register; however, using an uninitialized register
4631 // results in less predictable code. 4914 // results in less predictable code.
4632 // 4915 //
4633 // If in the future the implementation is changed to lower undef 4916 // If in the future the implementation is changed to lower undef
4634 // values to uninitialized registers, a FakeDef will be needed: 4917 // values to uninitialized registers, a FakeDef will be needed:
4635 // Context.insert(InstFakeDef::create(Func, Reg)); 4918 // Context.insert(InstFakeDef::create(Func, Reg));
4636 // This is in order to ensure that the live range of Reg is not 4919 // 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, 4920 // 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 4921 // then the result should be split and the lo and hi components will
4639 // need to go in uninitialized registers. 4922 // need to go in uninitialized registers.
4640 if (isVectorType(Ty)) 4923 if (isVectorType(Ty))
4641 return makeVectorOfZeros(Ty, RegNum); 4924 return makeVectorOfZeros(Ty, RegNum);
4642 From = Ctx->getConstantZero(Ty); 4925 From = Ctx->getConstantZero(Ty);
4643 } 4926 }
4644 // There should be no constants of vector type (other than undef). 4927 // There should be no constants of vector type (other than undef).
4645 assert(!isVectorType(Ty)); 4928 assert(!isVectorType(Ty));
4929
4930 // If the operand is an 32 bit constant integer, we should check
4931 // whether we need to randomize it or pool it.
4932 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(From)) {
4933 Operand *NewFrom = randomizeOrPoolImmediate(C, RegNum);
4934 if (NewFrom != From) {
4935 return NewFrom;
4936 }
4937 }
4938
4646 // Convert a scalar floating point constant into an explicit 4939 // Convert a scalar floating point constant into an explicit
4647 // memory operand. 4940 // memory operand.
4648 if (isScalarFloatingType(Ty)) { 4941 if (isScalarFloatingType(Ty)) {
4649 Variable *Base = nullptr; 4942 Variable *Base = nullptr;
4650 std::string Buffer; 4943 std::string Buffer;
4651 llvm::raw_string_ostream StrBuf(Buffer); 4944 llvm::raw_string_ostream StrBuf(Buffer);
4652 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); 4945 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
4946 llvm::cast<Constant>(From)->shouldBePooled = true;
4653 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); 4947 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
4654 From = OperandX8632Mem::create(Func, Ty, Base, Offset); 4948 From = OperandX8632Mem::create(Func, Ty, Base, Offset);
4655 } 4949 }
4656 bool NeedsReg = false; 4950 bool NeedsReg = false;
4657 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) 4951 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
4658 // Immediate specifically not allowed 4952 // Immediate specifically not allowed
4659 NeedsReg = true; 4953 NeedsReg = true;
4660 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) 4954 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty))
4661 // On x86, FP constants are lowered to mem operands. 4955 // On x86, FP constants are lowered to mem operands.
4662 NeedsReg = true; 4956 NeedsReg = true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4699 bool IsSrc1ImmOrReg = false; 4993 bool IsSrc1ImmOrReg = false;
4700 if (llvm::isa<Constant>(Src1)) { 4994 if (llvm::isa<Constant>(Src1)) {
4701 IsSrc1ImmOrReg = true; 4995 IsSrc1ImmOrReg = true;
4702 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { 4996 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) {
4703 if (Var->hasReg()) 4997 if (Var->hasReg())
4704 IsSrc1ImmOrReg = true; 4998 IsSrc1ImmOrReg = true;
4705 } 4999 }
4706 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); 5000 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg);
4707 } 5001 }
4708 5002
4709 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Operand, Type Ty, 5003 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Opnd, Type Ty,
4710 bool DoLegalize) { 5004 bool DoLegalize) {
4711 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); 5005 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Opnd);
4712 // It may be the case that address mode optimization already creates 5006 // It may be the case that address mode optimization already creates
4713 // an OperandX8632Mem, so in that case it wouldn't need another level 5007 // an OperandX8632Mem, so in that case it wouldn't need another level
4714 // of transformation. 5008 // of transformation.
4715 if (!Mem) { 5009 if (!Mem) {
4716 Variable *Base = llvm::dyn_cast<Variable>(Operand); 5010 Variable *Base = llvm::dyn_cast<Variable>(Opnd);
4717 Constant *Offset = llvm::dyn_cast<Constant>(Operand); 5011 Constant *Offset = llvm::dyn_cast<Constant>(Opnd);
4718 assert(Base || Offset); 5012 assert(Base || Offset);
4719 if (Offset) { 5013 if (Offset) {
4720 // Make sure Offset is not undef. 5014 // qining: during memory operand building, we do not
4721 Offset = llvm::cast<Constant>(legalize(Offset)); 5015 // blind or pool the constant offset, we will work on
5016 // the whole memory operand later as one entity later,
5017 // this save one instruction. By turning blinding and
5018 // pooling off, we guarantee legalize(Offset) will return
5019 // a constant*
5020 {
5021 BoolFlagSaver B(RandomizationPoolingPaused, true);
5022
5023 Offset = llvm::cast<Constant>(legalize(Offset));
5024 }
5025
4722 assert(llvm::isa<ConstantInteger32>(Offset) || 5026 assert(llvm::isa<ConstantInteger32>(Offset) ||
4723 llvm::isa<ConstantRelocatable>(Offset)); 5027 llvm::isa<ConstantRelocatable>(Offset));
4724 } 5028 }
4725 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 5029 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
4726 } 5030 }
4727 return llvm::cast<OperandX8632Mem>(DoLegalize ? legalize(Mem) : Mem); 5031 // qining: do legalization, which contains randomization/pooling
5032 // or do randomization/pooling.
5033 return llvm::cast<OperandX8632Mem>(
5034 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
4728 } 5035 }
4729 5036
4730 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 5037 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
4731 // There aren't any 64-bit integer registers for x86-32. 5038 // There aren't any 64-bit integer registers for x86-32.
4732 assert(Type != IceType_i64); 5039 assert(Type != IceType_i64);
4733 Variable *Reg = Func->makeVariable(Type); 5040 Variable *Reg = Func->makeVariable(Type);
4734 if (RegNum == Variable::NoRegister) 5041 if (RegNum == Variable::NoRegister)
4735 Reg->setWeightInfinite(); 5042 Reg->setWeightInfinite();
4736 else 5043 else
4737 Reg->setRegNum(RegNum); 5044 Reg->setRegNum(RegNum);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
4958 typedef ConstantDouble IceType; 5265 typedef ConstantDouble IceType;
4959 static const Type Ty = IceType_f64; 5266 static const Type Ty = IceType_f64;
4960 static const char *TypeName; 5267 static const char *TypeName;
4961 static const char *AsmTag; 5268 static const char *AsmTag;
4962 static const char *PrintfString; 5269 static const char *PrintfString;
4963 }; 5270 };
4964 const char *PoolTypeConverter<double>::TypeName = "double"; 5271 const char *PoolTypeConverter<double>::TypeName = "double";
4965 const char *PoolTypeConverter<double>::AsmTag = ".quad"; 5272 const char *PoolTypeConverter<double>::AsmTag = ".quad";
4966 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; 5273 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
4967 5274
5275 // Add converter for int type constant pooling
5276 template <> struct PoolTypeConverter<int> {
5277 typedef uint32_t PrimitiveIntType;
5278 typedef ConstantInteger32 IceType;
5279 static const Type Ty = IceType_i32;
5280 static const char *TypeName;
5281 static const char *AsmTag;
5282 static const char *PrintfString;
5283 };
5284 const char *PoolTypeConverter<int>::TypeName = "i32";
5285 const char *PoolTypeConverter<int>::AsmTag = ".long";
5286 const char *PoolTypeConverter<int>::PrintfString = "0x%x";
5287
5288 // Add converter for int type constant pooling
5289 template <> struct PoolTypeConverter<short> {
5290 typedef uint32_t PrimitiveIntType;
5291 typedef ConstantInteger32 IceType;
5292 static const Type Ty = IceType_i16;
5293 static const char *TypeName;
5294 static const char *AsmTag;
5295 static const char *PrintfString;
5296 };
5297 const char *PoolTypeConverter<short>::TypeName = "i16";
5298 const char *PoolTypeConverter<short>::AsmTag = ".short";
5299 const char *PoolTypeConverter<short>::PrintfString = "0x%x";
5300
5301 // Add converter for int type constant pooling
5302 template <> struct PoolTypeConverter<char> {
5303 typedef uint32_t PrimitiveIntType;
5304 typedef ConstantInteger32 IceType;
5305 static const Type Ty = IceType_i8;
5306 static const char *TypeName;
5307 static const char *AsmTag;
5308 static const char *PrintfString;
5309 };
5310 const char *PoolTypeConverter<char>::TypeName = "i8";
5311 const char *PoolTypeConverter<char>::AsmTag = ".byte";
5312 const char *PoolTypeConverter<char>::PrintfString = "0x%x";
5313
4968 template <typename T> 5314 template <typename T>
4969 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) { 5315 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
4970 if (!ALLOW_DUMP) 5316 if (!ALLOW_DUMP)
4971 return; 5317 return;
4972 Ostream &Str = Ctx->getStrEmit(); 5318 Ostream &Str = Ctx->getStrEmit();
4973 Type Ty = T::Ty; 5319 Type Ty = T::Ty;
4974 SizeT Align = typeAlignInBytes(Ty); 5320 SizeT Align = typeAlignInBytes(Ty);
4975 ConstantList Pool = Ctx->getConstantPool(Ty); 5321 ConstantList Pool = Ctx->getConstantPool(Ty);
4976 5322
4977 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 5323 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
4978 << "\n"; 5324 << "\n";
4979 Str << "\t.align\t" << Align << "\n"; 5325 Str << "\t.align\t" << Align << "\n";
4980 for (Constant *C : Pool) { 5326 for (Constant *C : Pool) {
5327 if (!C->shouldBePooled)
5328 continue;
4981 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); 5329 typename T::IceType *Const = llvm::cast<typename T::IceType>(C);
4982 typename T::IceType::PrimType Value = Const->getValue(); 5330 typename T::IceType::PrimType Value = Const->getValue();
4983 // Use memcpy() to copy bits from Value into RawValue in a way 5331 // Use memcpy() to copy bits from Value into RawValue in a way
4984 // that avoids breaking strict-aliasing rules. 5332 // that avoids breaking strict-aliasing rules.
4985 typename T::PrimitiveIntType RawValue; 5333 typename T::PrimitiveIntType RawValue;
4986 memcpy(&RawValue, &Value, sizeof(Value)); 5334 memcpy(&RawValue, &Value, sizeof(Value));
4987 char buf[30]; 5335 char buf[30];
4988 int CharsPrinted = 5336 int CharsPrinted =
4989 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 5337 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
4990 assert(CharsPrinted >= 0 && 5338 assert(CharsPrinted >= 0 &&
4991 (size_t)CharsPrinted < llvm::array_lengthof(buf)); 5339 (size_t)CharsPrinted < llvm::array_lengthof(buf));
4992 (void)CharsPrinted; // avoid warnings if asserts are disabled 5340 (void)CharsPrinted; // avoid warnings if asserts are disabled
4993 Const->emitPoolLabel(Str); 5341 Const->emitPoolLabel(Str);
4994 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " 5342 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
4995 << Value << "\n"; 5343 << Value << "\n";
4996 } 5344 }
4997 } 5345 }
4998 5346
4999 void TargetDataX8632::lowerConstants() const { 5347 void TargetDataX8632::lowerConstants() const {
5000 if (Ctx->getFlags().getDisableTranslation()) 5348 if (Ctx->getFlags().getDisableTranslation())
5001 return; 5349 return;
5002 // No need to emit constants from the int pool since (for x86) they 5350 // 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. 5351 // are embedded as immediates in the instructions, just emit float/double.
5004 switch (Ctx->getFlags().getOutFileType()) { 5352 switch (Ctx->getFlags().getOutFileType()) {
5005 case FT_Elf: { 5353 case FT_Elf: {
5006 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 5354 ELFObjectWriter *Writer = Ctx->getObjectWriter();
5355
5356 // If immediates pooling turned on, pool the integer constants
5357 // if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5358 // Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
5359 // Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
5360 // Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
5361 //}
5362
5363 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
5364 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
5365 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
5366
qining 2015/06/17 04:28:55 I will remove the commented if statement. That is
5007 Writer->writeConstantPool<ConstantFloat>(IceType_f32); 5367 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
5008 Writer->writeConstantPool<ConstantDouble>(IceType_f64); 5368 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
5009 } break; 5369 } break;
5010 case FT_Asm: 5370 case FT_Asm:
5011 case FT_Iasm: { 5371 case FT_Iasm: {
5012 OstreamLocker L(Ctx); 5372 OstreamLocker L(Ctx);
5373
5374 // If immediates pooling turned on, pool the integer constants
5375 // if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5376 // emitConstantPool<PoolTypeConverter<char>>(Ctx);
5377 // emitConstantPool<PoolTypeConverter<short>>(Ctx);
5378 // emitConstantPool<PoolTypeConverter<int>>(Ctx);
5379 //}
5380
5381 emitConstantPool<PoolTypeConverter<char>>(Ctx);
5382 emitConstantPool<PoolTypeConverter<short>>(Ctx);
5383 emitConstantPool<PoolTypeConverter<int>>(Ctx);
5384
5013 emitConstantPool<PoolTypeConverter<float>>(Ctx); 5385 emitConstantPool<PoolTypeConverter<float>>(Ctx);
5014 emitConstantPool<PoolTypeConverter<double>>(Ctx); 5386 emitConstantPool<PoolTypeConverter<double>>(Ctx);
5015 } break; 5387 } break;
5016 } 5388 }
5017 } 5389 }
5018 5390
5019 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) 5391 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
5020 : TargetHeaderLowering(Ctx) {} 5392 : TargetHeaderLowering(Ctx) {}
5021 5393
5394 // Blind/pool an Immediate
5395 Operand *TargetX8632::randomizeOrPoolImmediate(Constant *Immediate,
5396 int32_t RegNum) {
5397 assert(llvm::isa<ConstantInteger32>(Immediate) ||
5398 llvm::isa<ConstantRelocatable>(Immediate));
5399 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5400 RandomizationPoolingPaused == true) {
5401 // immediates randomization/pool turned off
5402 return Immediate;
5403 }
5404 if (Constant *C = llvm::dyn_cast_or_null<Constant>(Immediate)) {
5405 if (C->shouldBeRandomizedOrPooled(Ctx)) {
5406 Ctx->statsUpdateRPImms();
5407 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5408 RPI_Randomize) {
5409 // blind the constant
5410 // FROM:
5411 // imm
5412 // TO:
5413 // insert: mov imm+cookie, Reg
5414 // insert: lea -cookie[Reg], Reg
5415 // => Reg
5416 // If we have already assigned a phy register, we must come from
5417 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5418 // the assigned register as this assignment is that start of its use-def
5419 // chain. So we add RegNum argument here.
5420 Variable *Reg = makeReg(IceType_i32, RegNum);
5421 ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate);
5422 uint32_t Value = Integer->getValue();
5423 uint32_t Cookie = Ctx->getRandomizationCookie();
5424 _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
5425 Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
5426 _lea(Reg,
5427 OperandX8632Mem::create(Func, IceType_i32, Reg, Offset, NULL, 0));
5428 // make sure liveness analysis won't kill this variable, otherwise a
5429 // liveness
5430 // assertion will be triggered.
5431 _set_dest_nonkillable();
5432 if (Immediate->getType() != IceType_i32) {
5433 Variable *TruncReg = makeReg(Immediate->getType(), RegNum);
5434 _mov(TruncReg, Reg);
5435 return TruncReg;
5436 }
5437 return Reg;
5438 }
5439 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5440 // pool the constant
5441 // FROM:
5442 // imm
5443 // TO:
5444 // insert: mov $label, Reg
5445 // => Reg
5446 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5447 RPI_Pool);
5448 Immediate->shouldBePooled = true;
5449 // if we have already assigned a phy register, we must come from
5450 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5451 // the assigned register as this assignment is that start of its use-def
5452 // chain. So we add RegNum argument here.
5453 Variable *Reg = makeReg(Immediate->getType(), RegNum);
5454 IceString Label;
5455 llvm::raw_string_ostream Label_stream(Label);
5456 Immediate->emitPoolLabel(Label_stream);
5457 const RelocOffsetT Offset = 0;
5458 const bool SuppressMangling = true;
5459 Constant *Symbol =
5460 Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
5461 OperandX8632Mem *MemOperand =
5462 OperandX8632Mem::create(Func, Immediate->getType(), NULL, Symbol);
5463 _mov(Reg, MemOperand);
5464 return Reg;
5465 }
5466 assert("Unsupported -randomize-pool-immediates option" && false);
5467 }
5468 }
5469 // the constant Immediate is not eligible for blinding/pooling
5470 return Immediate;
5471 }
5472
5473 OperandX8632Mem *
5474 TargetX8632::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
5475 int32_t RegNum) {
5476 assert(MemOperand);
5477 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5478 RandomizationPoolingPaused == true) {
5479 // immediates randomization/pooling is turned off
5480 return MemOperand;
5481 }
5482
5483 if (Constant *C = llvm::dyn_cast_or_null<Constant>(MemOperand->getOffset())) {
5484 if (C->shouldBeRandomizedOrPooled(Ctx)) {
5485 // The offset of this mem operand should be blinded or pooled
5486 Ctx->statsUpdateRPImms();
5487 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5488 RPI_Randomize) {
5489 // blind the constant offset
5490 // FROM:
5491 // offset[base, index, shift]
5492 // TO:
5493 // insert: lea offset+cookie[base], RegTemp
5494 // => -cookie[RegTemp, index, shift]
5495 uint32_t Value =
5496 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
5497 ->getValue();
5498 uint64_t Cookie = Ctx->getRandomizationCookie();
5499 Constant *Mask1 = Ctx->getConstantInt(
5500 MemOperand->getOffset()->getType(), Cookie + Value);
5501 Constant *Mask2 =
5502 Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
5503 // qining: We need to make sure the MemOperand->getBase() has a physical
5504 // register, if it is a variable!
5505 if (MemOperand->getBase() != NULL)
5506 MemOperand->getBase()->setWeightInfinite();
5507 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
5508 Func, MemOperand->getType(), MemOperand->getBase(), Mask1);
5509 // If we have already assigned a physical register, we must come from
5510 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse
5511 // the assigned register as this assignment is that start of its use-def
5512 // chain. So we add RegNum argument here.
5513 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum);
5514 _lea(RegTemp, TempMemOperand);
5515 // As source operand doesn't use the dstreg, we don't need to add
5516 // _set_dest_nonkillable().
5517 // qining: but if we use the same Dest Reg, that is, with RegNum
5518 // assigned, we should add this _set_dest_nonkillable()
5519 if (RegNum != Variable::NoRegister)
5520 _set_dest_nonkillable();
5521
5522 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5523 Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
5524 MemOperand->getShift(), MemOperand->getSegmentRegister());
5525
5526 return NewMemOperand;
5527 }
5528 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5529 // pool the constant offset
5530 // FROM:
5531 // offset[base, index, shift]
5532 // TO:
5533 // insert: mov $label, RegTemp
5534 // insert: lea [base, RegTemp], RegTemp
5535 // =>[RegTemp, index, shift]
5536 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5537 RPI_Pool);
5538 // qining: Mem operand should never exist as source operands in phi
5539 // lowering
5540 // assignments, so there is no need to reuse any registers here.
5541 // However, for phi lowering, we should not ask for new physical
5542 // registers in general.
5543 // However, if we do meet MemOperand during phi lowering, we should not
5544 // blind or pool the immediates for now
5545 if (RegNum != Variable::NoRegister)
5546 return MemOperand;
5547 Variable *RegTemp = makeReg(IceType_i32);
5548 IceString Label;
5549 llvm::raw_string_ostream Label_stream(Label);
5550 MemOperand->getOffset()->emitPoolLabel(Label_stream);
5551 MemOperand->getOffset()->shouldBePooled = true;
5552 const RelocOffsetT SymOffset = 0;
5553 bool SuppressMangling = true;
5554 Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
5555 SuppressMangling);
5556 OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
5557 Func, MemOperand->getOffset()->getType(), NULL, Symbol);
5558 _mov(RegTemp, SymbolOperand);
5559 // qining: We need to make sure the MemOperand->getBase() has a physical
5560 // register! If we do not have base register here, we won't need an
5561 // extra lea instruction anymore.
5562 if (MemOperand->getBase()) {
5563 MemOperand->getBase()->setWeightInfinite();
5564 OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
5565 Func, MemOperand->getType(), MemOperand->getBase(), NULL, RegTemp,
5566 0, MemOperand->getSegmentRegister());
5567 _lea(RegTemp, CalculateOperand);
5568 _set_dest_nonkillable();
5569 }
5570 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5571 Func, MemOperand->getType(), RegTemp, NULL, MemOperand->getIndex(),
5572 MemOperand->getShift(), MemOperand->getSegmentRegister());
5573 return NewMemOperand;
5574 }
5575 assert("Unsupported -randomize-pool-immediates option" && false);
5576 }
5577 }
5578 // the offset is not eligible for blinding or pooling, return the original
5579 // mem operand
5580 return MemOperand;
5581 }
5582
5022 } // end of namespace Ice 5583 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698