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

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: Add bool flag: Randomized to OperandX8632Mem class, fix comments, rebased to master:b0a8c24ecd98f4b… 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 408 }
390 } 409 }
391 410
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), InstructionSet(X86InstructionSet::Begin), 417 : TargetLowering(Func), InstructionSet(X86InstructionSet::Begin),
399 IsEbpBasedFrame(false), NeedsStackAlignment(false), 418 IsEbpBasedFrame(false), NeedsStackAlignment(false), SpillAreaSizeBytes(0),
400 SpillAreaSizeBytes(0) { 419 RandomizationPoolingPaused(false) {
401 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) == 420 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) ==
402 (TargetInstructionSet::X86InstructionSet_End - 421 (TargetInstructionSet::X86InstructionSet_End -
403 TargetInstructionSet::X86InstructionSet_Begin), 422 TargetInstructionSet::X86InstructionSet_Begin),
404 "X86InstructionSet range different from TargetInstructionSet"); 423 "X86InstructionSet range different from TargetInstructionSet");
405 if (Func->getContext()->getFlags().getTargetInstructionSet() != 424 if (Func->getContext()->getFlags().getTargetInstructionSet() !=
406 TargetInstructionSet::BaseInstructionSet) { 425 TargetInstructionSet::BaseInstructionSet) {
407 InstructionSet = static_cast<X86InstructionSet>( 426 InstructionSet = static_cast<X86InstructionSet>(
408 (Func->getContext()->getFlags().getTargetInstructionSet() - 427 (Func->getContext()->getFlags().getTargetInstructionSet() -
409 TargetInstructionSet::X86InstructionSet_Begin) + 428 TargetInstructionSet::X86InstructionSet_Begin) +
410 X86InstructionSet::Begin); 429 X86InstructionSet::Begin);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 return; 504 return;
486 505
487 // TODO: It should be sufficient to use the fastest liveness 506 // TODO: It should be sufficient to use the fastest liveness
488 // calculation, i.e. livenessLightweight(). However, for some 507 // calculation, i.e. livenessLightweight(). However, for some
489 // reason that slows down the rest of the translation. Investigate. 508 // reason that slows down the rest of the translation. Investigate.
490 Func->liveness(Liveness_Basic); 509 Func->liveness(Liveness_Basic);
491 if (Func->hasError()) 510 if (Func->hasError())
492 return; 511 return;
493 Func->dump("After x86 address mode opt"); 512 Func->dump("After x86 address mode opt");
494 513
495 doLoadOpt(); 514 // Disable constant blinding or pooling for load optimization.
515 {
516 BoolFlagSaver B(RandomizationPoolingPaused, true);
517 doLoadOpt();
518 }
496 Func->genCode(); 519 Func->genCode();
497 if (Func->hasError()) 520 if (Func->hasError())
498 return; 521 return;
499 Func->dump("After x86 codegen"); 522 Func->dump("After x86 codegen");
500 523
501 // Register allocation. This requires instruction renumbering and 524 // Register allocation. This requires instruction renumbering and
502 // full liveness analysis. 525 // full liveness analysis.
503 Func->renumberInstructions(); 526 Func->renumberInstructions();
504 if (Func->hasError()) 527 if (Func->hasError())
505 return; 528 return;
506 Func->liveness(Liveness_Intervals); 529 Func->liveness(Liveness_Intervals);
507 if (Func->hasError()) 530 if (Func->hasError())
508 return; 531 return;
509 // Validate the live range computations. The expensive validation 532 // Validate the live range computations. The expensive validation
510 // call is deliberately only made when assertions are enabled. 533 // call is deliberately only made when assertions are enabled.
511 assert(Func->validateLiveness()); 534 assert(Func->validateLiveness());
512 // The post-codegen dump is done here, after liveness analysis and 535 // The post-codegen dump is done here, after liveness analysis and
513 // associated cleanup, to make the dump cleaner and more useful. 536 // associated cleanup, to make the dump cleaner and more useful.
514 Func->dump("After initial x8632 codegen"); 537 Func->dump("After initial x8632 codegen");
515 Func->getVMetadata()->init(VMK_All); 538 Func->getVMetadata()->init(VMK_All);
516 regAlloc(RAK_Global); 539 regAlloc(RAK_Global);
517 if (Func->hasError()) 540 if (Func->hasError())
518 return; 541 return;
519 Func->dump("After linear scan regalloc"); 542 Func->dump("After linear scan regalloc");
520 543
521 if (Ctx->getFlags().getPhiEdgeSplit()) { 544 if (Ctx->getFlags().getPhiEdgeSplit()) {
522 Func->advancedPhiLowering(); 545 // We need to pause constant blinding or pooling during advanced
546 // phi lowering, unless the lowering assignment has a physical
547 // register for the dest Variable.
548 {
549 BoolFlagSaver B(RandomizationPoolingPaused, true);
550 Func->advancedPhiLowering();
551 }
523 Func->dump("After advanced Phi lowering"); 552 Func->dump("After advanced Phi lowering");
524 } 553 }
525 554
526 // Stack frame mapping. 555 // Stack frame mapping.
527 Func->genFrame(); 556 Func->genFrame();
528 if (Func->hasError()) 557 if (Func->hasError())
529 return; 558 return;
530 Func->dump("After stack frame mapping"); 559 Func->dump("After stack frame mapping");
531 560
532 Func->contractEmptyNodes(); 561 Func->contractEmptyNodes();
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 return RegNames[RegNum]; 933 return RegNames[RegNum];
905 } 934 }
906 } 935 }
907 936
908 void TargetX8632::emitVariable(const Variable *Var) const { 937 void TargetX8632::emitVariable(const Variable *Var) const {
909 Ostream &Str = Ctx->getStrEmit(); 938 Ostream &Str = Ctx->getStrEmit();
910 if (Var->hasReg()) { 939 if (Var->hasReg()) {
911 Str << "%" << getRegName(Var->getRegNum(), Var->getType()); 940 Str << "%" << getRegName(Var->getRegNum(), Var->getType());
912 return; 941 return;
913 } 942 }
914 if (Var->getWeight().isInf()) 943 if (Var->getWeight().isInf()) {
915 llvm_unreachable("Infinite-weight Variable has no register assigned"); 944 llvm_unreachable("Infinite-weight Variable has no register assigned");
945 }
916 int32_t Offset = Var->getStackOffset(); 946 int32_t Offset = Var->getStackOffset();
917 if (!hasFramePointer()) 947 if (!hasFramePointer())
918 Offset += getStackAdjustment(); 948 Offset += getStackAdjustment();
919 if (Offset) 949 if (Offset)
920 Str << Offset; 950 Str << Offset;
921 const Type FrameSPTy = IceType_i32; 951 const Type FrameSPTy = IceType_i32;
922 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")"; 952 Str << "(%" << getRegName(getFrameOrStackReg(), FrameSPTy) << ")";
923 } 953 }
924 954
925 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const { 955 X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const {
926 if (Var->hasReg()) 956 if (Var->hasReg())
927 llvm_unreachable("Stack Variable has a register assigned"); 957 llvm_unreachable("Stack Variable has a register assigned");
928 if (Var->getWeight().isInf()) 958 if (Var->getWeight().isInf()) {
929 llvm_unreachable("Infinite-weight Variable has no register assigned"); 959 llvm_unreachable("Infinite-weight Variable has no register assigned");
960 }
930 int32_t Offset = Var->getStackOffset(); 961 int32_t Offset = Var->getStackOffset();
931 if (!hasFramePointer()) 962 if (!hasFramePointer())
932 Offset += getStackAdjustment(); 963 Offset += getStackAdjustment();
933 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset); 964 return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset);
934 } 965 }
935 966
936 void TargetX8632::lowerArguments() { 967 void TargetX8632::lowerArguments() {
937 VarList &Args = Func->getArgs(); 968 VarList &Args = Func->getArgs();
938 // The first four arguments of vector type, regardless of their 969 // The first four arguments of vector type, regardless of their
939 // position relative to the other arguments in the argument list, are 970 // position relative to the other arguments in the argument list, are
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 Operand *TargetX8632::loOperand(Operand *Operand) { 1341 Operand *TargetX8632::loOperand(Operand *Operand) {
1311 assert(Operand->getType() == IceType_i64 || 1342 assert(Operand->getType() == IceType_i64 ||
1312 Operand->getType() == IceType_f64); 1343 Operand->getType() == IceType_f64);
1313 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1344 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1314 return Operand; 1345 return Operand;
1315 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1346 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1316 split64(Var); 1347 split64(Var);
1317 return Var->getLo(); 1348 return Var->getLo();
1318 } 1349 }
1319 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1350 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1320 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 1351 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
1352 Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue())));
1353 return legalize(ConstInt);
1321 } 1354 }
1322 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1355 if (OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(Operand)) {
1323 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 1356 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1324 Mem->getOffset(), Mem->getIndex(), 1357 Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
1325 Mem->getShift(), Mem->getSegmentRegister()); 1358 Mem->getShift(), Mem->getSegmentRegister());
1359 // Test if we should randomize or pool the offset, if so randomize it or
1360 // pool it then create mem operand with the blinded/pooled constant.
1361 // Otherwise, return the mem operand as ordinary mem operand.
1362 return legalize(MemOperand);
1326 } 1363 }
1327 llvm_unreachable("Unsupported operand type"); 1364 llvm_unreachable("Unsupported operand type");
1328 return nullptr; 1365 return nullptr;
1329 } 1366 }
1330 1367
1331 Operand *TargetX8632::hiOperand(Operand *Operand) { 1368 Operand *TargetX8632::hiOperand(Operand *Operand) {
1332 assert(Operand->getType() == IceType_i64 || 1369 assert(Operand->getType() == IceType_i64 ||
1333 Operand->getType() == IceType_f64); 1370 Operand->getType() == IceType_f64);
1334 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) 1371 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1335 return Operand; 1372 return Operand;
1336 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1373 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1337 split64(Var); 1374 split64(Var);
1338 return Var->getHi(); 1375 return Var->getHi();
1339 } 1376 }
1340 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1377 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1341 return Ctx->getConstantInt32( 1378 ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>(
1342 static_cast<uint32_t>(Const->getValue() >> 32)); 1379 Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue() >> 32)));
1380 // check if we need to blind/pool the constant
1381 return legalize(ConstInt);
1343 } 1382 }
1344 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1383 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
1345 Constant *Offset = Mem->getOffset(); 1384 Constant *Offset = Mem->getOffset();
1346 if (Offset == nullptr) { 1385 if (Offset == nullptr) {
1347 Offset = Ctx->getConstantInt32(4); 1386 Offset = Ctx->getConstantInt32(4);
1348 } else if (ConstantInteger32 *IntOffset = 1387 } else if (ConstantInteger32 *IntOffset =
1349 llvm::dyn_cast<ConstantInteger32>(Offset)) { 1388 llvm::dyn_cast<ConstantInteger32>(Offset)) {
1350 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue()); 1389 Offset = Ctx->getConstantInt32(4 + IntOffset->getValue());
1351 } else if (ConstantRelocatable *SymOffset = 1390 } else if (ConstantRelocatable *SymOffset =
1352 llvm::dyn_cast<ConstantRelocatable>(Offset)) { 1391 llvm::dyn_cast<ConstantRelocatable>(Offset)) {
1353 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4)); 1392 assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4));
1354 Offset = 1393 Offset =
1355 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(), 1394 Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
1356 SymOffset->getSuppressMangling()); 1395 SymOffset->getSuppressMangling());
1357 } 1396 }
1358 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, 1397 OperandX8632Mem *MemOperand = OperandX8632Mem::create(
1359 Mem->getIndex(), Mem->getShift(), 1398 Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
1360 Mem->getSegmentRegister()); 1399 Mem->getShift(), Mem->getSegmentRegister());
1400 // Test if the Offset is an eligible i32 constants for randomization and
1401 // pooling. Blind/pool it if it is. Otherwise return as oridinary mem
1402 // operand.
1403 return legalize(MemOperand);
1361 } 1404 }
1362 llvm_unreachable("Unsupported operand type"); 1405 llvm_unreachable("Unsupported operand type");
1363 return nullptr; 1406 return nullptr;
1364 } 1407 }
1365 1408
1366 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, 1409 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
1367 RegSetMask Exclude) const { 1410 RegSetMask Exclude) const {
1368 llvm::SmallBitVector Registers(RegX8632::Reg_NUM); 1411 llvm::SmallBitVector Registers(RegX8632::Reg_NUM);
1369 1412
1370 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ 1413 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 Variable *Dest = Inst->getDest(); 1579 Variable *Dest = Inst->getDest();
1537 Operand *Src0 = legalize(Inst->getSrc(0)); 1580 Operand *Src0 = legalize(Inst->getSrc(0));
1538 Operand *Src1 = legalize(Inst->getSrc(1)); 1581 Operand *Src1 = legalize(Inst->getSrc(1));
1539 if (Inst->isCommutative()) { 1582 if (Inst->isCommutative()) {
1540 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) 1583 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1))
1541 std::swap(Src0, Src1); 1584 std::swap(Src0, Src1);
1542 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) 1585 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1))
1543 std::swap(Src0, Src1); 1586 std::swap(Src0, Src1);
1544 } 1587 }
1545 if (Dest->getType() == IceType_i64) { 1588 if (Dest->getType() == IceType_i64) {
1589 switch (Inst->getOp()) {
1590 case InstArithmetic::Udiv: {
1591 const SizeT MaxSrcs = 2;
1592 InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
1593 Call->addArg(Inst->getSrc(0));
1594 Call->addArg(Inst->getSrc(1));
1595 lowerCall(Call);
1596 return;
1597 }
1598 case InstArithmetic::Sdiv: {
1599 const SizeT MaxSrcs = 2;
1600 InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
1601 Call->addArg(Inst->getSrc(0));
1602 Call->addArg(Inst->getSrc(1));
1603 lowerCall(Call);
1604 return;
1605 }
1606 case InstArithmetic::Urem: {
1607 const SizeT MaxSrcs = 2;
1608 InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
1609 Call->addArg(Inst->getSrc(0));
1610 Call->addArg(Inst->getSrc(1));
1611 lowerCall(Call);
1612 return;
1613 }
1614 case InstArithmetic::Srem: {
1615 const SizeT MaxSrcs = 2;
1616 InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
1617 Call->addArg(Inst->getSrc(0));
1618 Call->addArg(Inst->getSrc(1));
1619 lowerCall(Call);
1620 return;
1621 }
1622 default:
1623 break;
1624 }
1625
1546 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1626 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1547 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1627 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1548 Operand *Src0Lo = loOperand(Src0); 1628 Operand *Src0Lo = loOperand(Src0);
1549 Operand *Src0Hi = hiOperand(Src0); 1629 Operand *Src0Hi = hiOperand(Src0);
1550 Operand *Src1Lo = loOperand(Src1); 1630 Operand *Src1Lo = loOperand(Src1);
1551 Operand *Src1Hi = hiOperand(Src1); 1631 Operand *Src1Hi = hiOperand(Src1);
1552 Variable *T_Lo = nullptr, *T_Hi = nullptr; 1632 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1553 switch (Inst->getOp()) { 1633 switch (Inst->getOp()) {
1554 case InstArithmetic::_num: 1634 case InstArithmetic::_num:
1555 llvm_unreachable("Unknown arithmetic operator"); 1635 llvm_unreachable("Unknown arithmetic operator");
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 // T_2 and T_3 are being assigned again because of the 1805 // T_2 and T_3 are being assigned again because of the
1726 // intra-block control flow, so T_2 needs the _mov_nonkillable 1806 // intra-block control flow, so T_2 needs the _mov_nonkillable
1727 // variant to avoid liveness problems. T_3 doesn't need special 1807 // variant to avoid liveness problems. T_3 doesn't need special
1728 // treatment because it is reassigned via _sar instead of _mov. 1808 // treatment because it is reassigned via _sar instead of _mov.
1729 _mov_nonkillable(T_2, T_3); 1809 _mov_nonkillable(T_2, T_3);
1730 _sar(T_3, SignExtend); 1810 _sar(T_3, SignExtend);
1731 Context.insert(Label); 1811 Context.insert(Label);
1732 _mov(DestLo, T_2); 1812 _mov(DestLo, T_2);
1733 _mov(DestHi, T_3); 1813 _mov(DestHi, T_3);
1734 } break; 1814 } break;
1735 case InstArithmetic::Udiv: {
1736 const SizeT MaxSrcs = 2;
1737 InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
1738 Call->addArg(Inst->getSrc(0));
1739 Call->addArg(Inst->getSrc(1));
1740 lowerCall(Call);
1741 } break;
1742 case InstArithmetic::Sdiv: {
1743 const SizeT MaxSrcs = 2;
1744 InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
1745 Call->addArg(Inst->getSrc(0));
1746 Call->addArg(Inst->getSrc(1));
1747 lowerCall(Call);
1748 } break;
1749 case InstArithmetic::Urem: {
1750 const SizeT MaxSrcs = 2;
1751 InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
1752 Call->addArg(Inst->getSrc(0));
1753 Call->addArg(Inst->getSrc(1));
1754 lowerCall(Call);
1755 } break;
1756 case InstArithmetic::Srem: {
1757 const SizeT MaxSrcs = 2;
1758 InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
1759 Call->addArg(Inst->getSrc(0));
1760 Call->addArg(Inst->getSrc(1));
1761 lowerCall(Call);
1762 } break;
1763 case InstArithmetic::Fadd: 1815 case InstArithmetic::Fadd:
1764 case InstArithmetic::Fsub: 1816 case InstArithmetic::Fsub:
1765 case InstArithmetic::Fmul: 1817 case InstArithmetic::Fmul:
1766 case InstArithmetic::Fdiv: 1818 case InstArithmetic::Fdiv:
1767 case InstArithmetic::Frem: 1819 case InstArithmetic::Frem:
1768 llvm_unreachable("FP instruction with i64 type"); 1820 llvm_unreachable("FP instruction with i64 type");
1769 break; 1821 break;
1822 default:
1823 llvm_unreachable("Unknown instruction with i64 type");
1824 break;
1770 } 1825 }
1771 return; 1826 return;
1772 } 1827 }
1773 if (isVectorType(Dest->getType())) { 1828 if (isVectorType(Dest->getType())) {
1774 // TODO: Trap on integer divide and integer modulo by zero. 1829 // TODO: Trap on integer divide and integer modulo by zero.
1775 // See: https://code.google.com/p/nativeclient/issues/detail?id=3899 1830 // See: https://code.google.com/p/nativeclient/issues/detail?id=3899
1776 if (llvm::isa<OperandX8632Mem>(Src1)) 1831 if (llvm::isa<OperandX8632Mem>(Src1))
1777 Src1 = legalizeToVar(Src1); 1832 Src1 = legalizeToVar(Src1);
1778 switch (Inst->getOp()) { 1833 switch (Inst->getOp()) {
1779 case InstArithmetic::_num: 1834 case InstArithmetic::_num:
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
2154 Operand *Src0Hi = hiOperand(Src0); 2209 Operand *Src0Hi = hiOperand(Src0);
2155 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2210 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2156 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2211 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2157 Variable *T_Lo = nullptr, *T_Hi = nullptr; 2212 Variable *T_Lo = nullptr, *T_Hi = nullptr;
2158 _mov(T_Lo, Src0Lo); 2213 _mov(T_Lo, Src0Lo);
2159 _mov(DestLo, T_Lo); 2214 _mov(DestLo, T_Lo);
2160 _mov(T_Hi, Src0Hi); 2215 _mov(T_Hi, Src0Hi);
2161 _mov(DestHi, T_Hi); 2216 _mov(DestHi, T_Hi);
2162 } else { 2217 } else {
2163 Operand *RI; 2218 Operand *RI;
2164 if (Dest->hasReg()) 2219 if (Dest->hasReg()) {
2165 // If Dest already has a physical register, then legalize the 2220 // If Dest already has a physical register, then legalize the
2166 // Src operand into a Variable with the same register 2221 // Src operand into a Variable with the same register
2167 // assignment. This is mostly a workaround for advanced phi 2222 // assignment. This is mostly a workaround for advanced phi
2168 // lowering's ad-hoc register allocation which assumes no 2223 // lowering's ad-hoc register allocation which assumes no
2169 // register allocation is needed when at least one of the 2224 // register allocation is needed when at least one of the
2170 // operands is non-memory. 2225 // operands is non-memory.
2171 RI = legalize(Src0, Legal_Reg, Dest->getRegNum()); 2226
2172 else 2227 // If we have a physical register for the dest variable, we can
2228 // enable our constant blinding or pooling again. Note this is
2229 // only for advancedPhiLowering(), the flag flip should leave
2230 // no other side effect.
2231 {
2232 BoolFlagSaver B(RandomizationPoolingPaused, false);
2233 RI = legalize(Src0, Legal_Reg, Dest->getRegNum());
2234 }
2235 } else {
2173 // If Dest could be a stack operand, then RI must be a physical 2236 // If Dest could be a stack operand, then RI must be a physical
2174 // register or a scalar integer immediate. 2237 // register or a scalar integer immediate.
2175 RI = legalize(Src0, Legal_Reg | Legal_Imm); 2238 RI = legalize(Src0, Legal_Reg | Legal_Imm);
2239 }
2176 if (isVectorType(Dest->getType())) 2240 if (isVectorType(Dest->getType()))
2177 _movp(Dest, RI); 2241 _movp(Dest, RI);
2178 else 2242 else
2179 _mov(Dest, RI); 2243 _mov(Dest, RI);
2180 } 2244 }
2181 } 2245 }
2182 2246
2183 void TargetX8632::lowerBr(const InstBr *Inst) { 2247 void TargetX8632::lowerBr(const InstBr *Inst) {
2184 if (Inst->isUnconditional()) { 2248 if (Inst->isUnconditional()) {
2185 _br(Inst->getTargetUnconditional()); 2249 _br(Inst->getTargetUnconditional());
(...skipping 2540 matching lines...) Expand 10 before | Expand all | Expand 10 after
4726 } else { 4790 } else {
4727 TargetLowering::lowerOther(Instr); 4791 TargetLowering::lowerOther(Instr);
4728 } 4792 }
4729 } 4793 }
4730 4794
4731 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to 4795 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
4732 // preserve integrity of liveness analysis. Undef values are also 4796 // preserve integrity of liveness analysis. Undef values are also
4733 // turned into zeroes, since loOperand() and hiOperand() don't expect 4797 // turned into zeroes, since loOperand() and hiOperand() don't expect
4734 // Undef input. 4798 // Undef input.
4735 void TargetX8632::prelowerPhis() { 4799 void TargetX8632::prelowerPhis() {
4800 // Pause constant blinding or pooling, blinding or pooling will be done later
4801 // during phi lowering assignments
4802 BoolFlagSaver B(RandomizationPoolingPaused, true);
4803
4736 CfgNode *Node = Context.getNode(); 4804 CfgNode *Node = Context.getNode();
4737 for (Inst &I : Node->getPhis()) { 4805 for (Inst &I : Node->getPhis()) {
4738 auto Phi = llvm::dyn_cast<InstPhi>(&I); 4806 auto Phi = llvm::dyn_cast<InstPhi>(&I);
4739 if (Phi->isDeleted()) 4807 if (Phi->isDeleted())
4740 continue; 4808 continue;
4741 Variable *Dest = Phi->getDest(); 4809 Variable *Dest = Phi->getDest();
4742 if (Dest->getType() == IceType_i64) { 4810 if (Dest->getType() == IceType_i64) {
4743 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 4811 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
4744 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 4812 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
4745 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo); 4813 InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4825 // assignment, add Dest to the set of available registers, and 4893 // assignment, add Dest to the set of available registers, and
4826 // remove Src from the set of available registers. Iteration is 4894 // remove Src from the set of available registers. Iteration is
4827 // done backwards to enable incremental updates of the available 4895 // done backwards to enable incremental updates of the available
4828 // register set, and the lowered instruction numbers may be out of 4896 // register set, and the lowered instruction numbers may be out of
4829 // order, but that can be worked around by renumbering the block 4897 // order, but that can be worked around by renumbering the block
4830 // afterwards if necessary. 4898 // afterwards if necessary.
4831 for (const Inst &I : reverse_range(Assignments)) { 4899 for (const Inst &I : reverse_range(Assignments)) {
4832 Context.rewind(); 4900 Context.rewind();
4833 auto Assign = llvm::dyn_cast<InstAssign>(&I); 4901 auto Assign = llvm::dyn_cast<InstAssign>(&I);
4834 Variable *Dest = Assign->getDest(); 4902 Variable *Dest = Assign->getDest();
4903
4904 // If the source operand is ConstantUndef, do not legalize it.
4905 // In function test_split_undef_int_vec, the advanced phi
4906 // lowering process will find an assignment of undefined
4907 // vector. This vector, as the Src here, will crash if it
4908 // go through legalize(). legalize() will create new variable
4909 // with makeVectorOfZeros(), but this new variable will be
4910 // assigned a stack slot. This will fail the assertion in
4911 // IceInstX8632.cpp:789, as XmmEmitterRegOp() complain:
4912 // Var->hasReg() fails. Note this failure is irrelevant to
4913 // randomization or pooling of constants.
4914 // So, we do not call legalize() to add pool label for the
4915 // src operands of phi assignment instructions.
4916 // Instead, we manually add pool label for constant float and
4917 // constant double values here.
4918 // Note going through legalize() does not affect the testing
4919 // results of SPEC2K and xtests.
4835 Operand *Src = Assign->getSrc(0); 4920 Operand *Src = Assign->getSrc(0);
4921 if (!llvm::isa<ConstantUndef>(Assign->getSrc(0))) {
4922 Src = legalize(Src);
4923 }
4924
4836 Variable *SrcVar = llvm::dyn_cast<Variable>(Src); 4925 Variable *SrcVar = llvm::dyn_cast<Variable>(Src);
4837 // Use normal assignment lowering, except lower mem=mem specially 4926 // Use normal assignment lowering, except lower mem=mem specially
4838 // so we can register-allocate at the same time. 4927 // so we can register-allocate at the same time.
4839 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) { 4928 if (!isMemoryOperand(Dest) || !isMemoryOperand(Src)) {
4840 lowerAssign(Assign); 4929 lowerAssign(Assign);
4841 } else { 4930 } else {
4842 assert(Dest->getType() == Src->getType()); 4931 assert(Dest->getType() == Src->getType());
4843 const llvm::SmallBitVector &RegsForType = 4932 const llvm::SmallBitVector &RegsForType =
4844 getRegisterSetForType(Dest->getType()); 4933 getRegisterSetForType(Dest->getType());
4845 llvm::SmallBitVector AvailRegsForType = RegsForType & Available; 4934 llvm::SmallBitVector AvailRegsForType = RegsForType & Available;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
5001 // Assert that a physical register is allowed. To date, all calls 5090 // Assert that a physical register is allowed. To date, all calls
5002 // to legalize() allow a physical register. If a physical register 5091 // to legalize() allow a physical register. If a physical register
5003 // needs to be explicitly disallowed, then new code will need to be 5092 // needs to be explicitly disallowed, then new code will need to be
5004 // written to force a spill. 5093 // written to force a spill.
5005 assert(Allowed & Legal_Reg); 5094 assert(Allowed & Legal_Reg);
5006 // If we're asking for a specific physical register, make sure we're 5095 // If we're asking for a specific physical register, make sure we're
5007 // not allowing any other operand kinds. (This could be future 5096 // not allowing any other operand kinds. (This could be future
5008 // work, e.g. allow the shl shift amount to be either an immediate 5097 // work, e.g. allow the shl shift amount to be either an immediate
5009 // or in ecx.) 5098 // or in ecx.)
5010 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); 5099 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg);
5100
5011 if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { 5101 if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) {
5012 // Before doing anything with a Mem operand, we need to ensure 5102 // Before doing anything with a Mem operand, we need to ensure
5013 // that the Base and Index components are in physical registers. 5103 // that the Base and Index components are in physical registers.
5014 Variable *Base = Mem->getBase(); 5104 Variable *Base = Mem->getBase();
5015 Variable *Index = Mem->getIndex(); 5105 Variable *Index = Mem->getIndex();
5016 Variable *RegBase = nullptr; 5106 Variable *RegBase = nullptr;
5017 Variable *RegIndex = nullptr; 5107 Variable *RegIndex = nullptr;
5018 if (Base) { 5108 if (Base) {
5019 RegBase = legalizeToVar(Base); 5109 RegBase = legalizeToVar(Base);
5020 } 5110 }
5021 if (Index) { 5111 if (Index) {
5022 RegIndex = legalizeToVar(Index); 5112 RegIndex = legalizeToVar(Index);
5023 } 5113 }
5024 if (Base != RegBase || Index != RegIndex) { 5114 if (Base != RegBase || Index != RegIndex) {
5025 From = 5115 Mem =
5026 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex, 5116 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
5027 Mem->getShift(), Mem->getSegmentRegister()); 5117 Mem->getShift(), Mem->getSegmentRegister());
5028 } 5118 }
5029 5119
5120 // For all Memory Operands, we do randomization/pooling here
5121 From = randomizeOrPoolImmediate(Mem);
5122
5030 if (!(Allowed & Legal_Mem)) { 5123 if (!(Allowed & Legal_Mem)) {
5031 From = copyToReg(From, RegNum); 5124 From = copyToReg(From, RegNum);
5032 } 5125 }
5033 return From; 5126 return From;
5034 } 5127 }
5035 if (llvm::isa<Constant>(From)) { 5128 if (llvm::isa<Constant>(From)) {
5036 if (llvm::isa<ConstantUndef>(From)) { 5129 if (llvm::isa<ConstantUndef>(From)) {
5037 // Lower undefs to zero. Another option is to lower undefs to an 5130 // Lower undefs to zero. Another option is to lower undefs to an
5038 // uninitialized register; however, using an uninitialized register 5131 // uninitialized register; however, using an uninitialized register
5039 // results in less predictable code. 5132 // results in less predictable code.
5040 // 5133 //
5041 // If in the future the implementation is changed to lower undef 5134 // If in the future the implementation is changed to lower undef
5042 // values to uninitialized registers, a FakeDef will be needed: 5135 // values to uninitialized registers, a FakeDef will be needed:
5043 // Context.insert(InstFakeDef::create(Func, Reg)); 5136 // Context.insert(InstFakeDef::create(Func, Reg));
5044 // This is in order to ensure that the live range of Reg is not 5137 // This is in order to ensure that the live range of Reg is not
5045 // overestimated. If the constant being lowered is a 64 bit value, 5138 // overestimated. If the constant being lowered is a 64 bit value,
5046 // then the result should be split and the lo and hi components will 5139 // then the result should be split and the lo and hi components will
5047 // need to go in uninitialized registers. 5140 // need to go in uninitialized registers.
5048 if (isVectorType(Ty)) 5141 if (isVectorType(Ty))
5049 return makeVectorOfZeros(Ty, RegNum); 5142 return makeVectorOfZeros(Ty, RegNum);
5050 From = Ctx->getConstantZero(Ty); 5143 From = Ctx->getConstantZero(Ty);
5051 } 5144 }
5052 // There should be no constants of vector type (other than undef). 5145 // There should be no constants of vector type (other than undef).
5053 assert(!isVectorType(Ty)); 5146 assert(!isVectorType(Ty));
5147
5148 // If the operand is an 32 bit constant integer, we should check
5149 // whether we need to randomize it or pool it.
5150 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(From)) {
5151 Operand *NewFrom = randomizeOrPoolImmediate(C, RegNum);
5152 if (NewFrom != From) {
5153 return NewFrom;
5154 }
5155 }
5156
5054 // Convert a scalar floating point constant into an explicit 5157 // Convert a scalar floating point constant into an explicit
5055 // memory operand. 5158 // memory operand.
5056 if (isScalarFloatingType(Ty)) { 5159 if (isScalarFloatingType(Ty)) {
5057 Variable *Base = nullptr; 5160 Variable *Base = nullptr;
5058 std::string Buffer; 5161 std::string Buffer;
5059 llvm::raw_string_ostream StrBuf(Buffer); 5162 llvm::raw_string_ostream StrBuf(Buffer);
5060 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); 5163 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
5164 llvm::cast<Constant>(From)->shouldBePooled = true;
5061 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); 5165 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
5062 From = OperandX8632Mem::create(Func, Ty, Base, Offset); 5166 From = OperandX8632Mem::create(Func, Ty, Base, Offset);
5063 } 5167 }
5064 bool NeedsReg = false; 5168 bool NeedsReg = false;
5065 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) 5169 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
5066 // Immediate specifically not allowed 5170 // Immediate specifically not allowed
5067 NeedsReg = true; 5171 NeedsReg = true;
5068 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) 5172 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty))
5069 // On x86, FP constants are lowered to mem operands. 5173 // On x86, FP constants are lowered to mem operands.
5070 NeedsReg = true; 5174 NeedsReg = true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5107 bool IsSrc1ImmOrReg = false; 5211 bool IsSrc1ImmOrReg = false;
5108 if (llvm::isa<Constant>(Src1)) { 5212 if (llvm::isa<Constant>(Src1)) {
5109 IsSrc1ImmOrReg = true; 5213 IsSrc1ImmOrReg = true;
5110 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { 5214 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) {
5111 if (Var->hasReg()) 5215 if (Var->hasReg())
5112 IsSrc1ImmOrReg = true; 5216 IsSrc1ImmOrReg = true;
5113 } 5217 }
5114 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); 5218 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg);
5115 } 5219 }
5116 5220
5117 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Operand, Type Ty, 5221 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Opnd, Type Ty,
5118 bool DoLegalize) { 5222 bool DoLegalize) {
5119 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); 5223 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Opnd);
5120 // It may be the case that address mode optimization already creates 5224 // It may be the case that address mode optimization already creates
5121 // an OperandX8632Mem, so in that case it wouldn't need another level 5225 // an OperandX8632Mem, so in that case it wouldn't need another level
5122 // of transformation. 5226 // of transformation.
5123 if (!Mem) { 5227 if (!Mem) {
5124 Variable *Base = llvm::dyn_cast<Variable>(Operand); 5228 Variable *Base = llvm::dyn_cast<Variable>(Opnd);
5125 Constant *Offset = llvm::dyn_cast<Constant>(Operand); 5229 Constant *Offset = llvm::dyn_cast<Constant>(Opnd);
5126 assert(Base || Offset); 5230 assert(Base || Offset);
5127 if (Offset) { 5231 if (Offset) {
5128 // Make sure Offset is not undef. 5232 // During memory operand building, we do not blind or pool
5129 Offset = llvm::cast<Constant>(legalize(Offset)); 5233 // the constant offset, we will work on the whole memory
5234 // operand later as one entity later, this save one instruction.
5235 // By turning blinding and pooling off, we guarantee
5236 // legalize(Offset) will return a constant*.
5237 {
5238 BoolFlagSaver B(RandomizationPoolingPaused, true);
5239
5240 Offset = llvm::cast<Constant>(legalize(Offset));
5241 }
5242
5130 assert(llvm::isa<ConstantInteger32>(Offset) || 5243 assert(llvm::isa<ConstantInteger32>(Offset) ||
5131 llvm::isa<ConstantRelocatable>(Offset)); 5244 llvm::isa<ConstantRelocatable>(Offset));
5132 } 5245 }
5133 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 5246 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
5134 } 5247 }
5135 return llvm::cast<OperandX8632Mem>(DoLegalize ? legalize(Mem) : Mem); 5248 // Do legalization, which contains randomization/pooling
5249 // or do randomization/pooling.
5250 return llvm::cast<OperandX8632Mem>(
5251 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
5136 } 5252 }
5137 5253
5138 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 5254 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
5139 // There aren't any 64-bit integer registers for x86-32. 5255 // There aren't any 64-bit integer registers for x86-32.
5140 assert(Type != IceType_i64); 5256 assert(Type != IceType_i64);
5141 Variable *Reg = Func->makeVariable(Type); 5257 Variable *Reg = Func->makeVariable(Type);
5142 if (RegNum == Variable::NoRegister) 5258 if (RegNum == Variable::NoRegister)
5143 Reg->setWeightInfinite(); 5259 Reg->setWeightInfinite();
5144 else 5260 else
5145 Reg->setRegNum(RegNum); 5261 Reg->setRegNum(RegNum);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
5290 typedef ConstantDouble IceType; 5406 typedef ConstantDouble IceType;
5291 static const Type Ty = IceType_f64; 5407 static const Type Ty = IceType_f64;
5292 static const char *TypeName; 5408 static const char *TypeName;
5293 static const char *AsmTag; 5409 static const char *AsmTag;
5294 static const char *PrintfString; 5410 static const char *PrintfString;
5295 }; 5411 };
5296 const char *PoolTypeConverter<double>::TypeName = "double"; 5412 const char *PoolTypeConverter<double>::TypeName = "double";
5297 const char *PoolTypeConverter<double>::AsmTag = ".quad"; 5413 const char *PoolTypeConverter<double>::AsmTag = ".quad";
5298 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; 5414 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
5299 5415
5416 // Add converter for int type constant pooling
5417 template <> struct PoolTypeConverter<int> {
5418 typedef uint32_t PrimitiveIntType;
5419 typedef ConstantInteger32 IceType;
5420 static const Type Ty = IceType_i32;
5421 static const char *TypeName;
5422 static const char *AsmTag;
5423 static const char *PrintfString;
5424 };
5425 const char *PoolTypeConverter<int>::TypeName = "i32";
5426 const char *PoolTypeConverter<int>::AsmTag = ".long";
5427 const char *PoolTypeConverter<int>::PrintfString = "0x%x";
5428
5429 // Add converter for int type constant pooling
5430 template <> struct PoolTypeConverter<short> {
5431 typedef uint32_t PrimitiveIntType;
5432 typedef ConstantInteger32 IceType;
5433 static const Type Ty = IceType_i16;
5434 static const char *TypeName;
5435 static const char *AsmTag;
5436 static const char *PrintfString;
5437 };
5438 const char *PoolTypeConverter<short>::TypeName = "i16";
5439 const char *PoolTypeConverter<short>::AsmTag = ".short";
5440 const char *PoolTypeConverter<short>::PrintfString = "0x%x";
5441
5442 // Add converter for int type constant pooling
5443 template <> struct PoolTypeConverter<char> {
5444 typedef uint32_t PrimitiveIntType;
5445 typedef ConstantInteger32 IceType;
5446 static const Type Ty = IceType_i8;
5447 static const char *TypeName;
5448 static const char *AsmTag;
5449 static const char *PrintfString;
5450 };
5451 const char *PoolTypeConverter<char>::TypeName = "i8";
5452 const char *PoolTypeConverter<char>::AsmTag = ".byte";
5453 const char *PoolTypeConverter<char>::PrintfString = "0x%x";
5454
5300 template <typename T> 5455 template <typename T>
5301 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) { 5456 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
5302 if (!ALLOW_DUMP) 5457 if (!ALLOW_DUMP)
5303 return; 5458 return;
5304 Ostream &Str = Ctx->getStrEmit(); 5459 Ostream &Str = Ctx->getStrEmit();
5305 Type Ty = T::Ty; 5460 Type Ty = T::Ty;
5306 SizeT Align = typeAlignInBytes(Ty); 5461 SizeT Align = typeAlignInBytes(Ty);
5307 ConstantList Pool = Ctx->getConstantPool(Ty); 5462 ConstantList Pool = Ctx->getConstantPool(Ty);
5308 5463
5309 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 5464 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
5310 << "\n"; 5465 << "\n";
5311 Str << "\t.align\t" << Align << "\n"; 5466 Str << "\t.align\t" << Align << "\n";
5312 for (Constant *C : Pool) { 5467 for (Constant *C : Pool) {
5468 if (!C->shouldBePooled)
5469 continue;
5313 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); 5470 typename T::IceType *Const = llvm::cast<typename T::IceType>(C);
5314 typename T::IceType::PrimType Value = Const->getValue(); 5471 typename T::IceType::PrimType Value = Const->getValue();
5315 // Use memcpy() to copy bits from Value into RawValue in a way 5472 // Use memcpy() to copy bits from Value into RawValue in a way
5316 // that avoids breaking strict-aliasing rules. 5473 // that avoids breaking strict-aliasing rules.
5317 typename T::PrimitiveIntType RawValue; 5474 typename T::PrimitiveIntType RawValue;
5318 memcpy(&RawValue, &Value, sizeof(Value)); 5475 memcpy(&RawValue, &Value, sizeof(Value));
5319 char buf[30]; 5476 char buf[30];
5320 int CharsPrinted = 5477 int CharsPrinted =
5321 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 5478 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
5322 assert(CharsPrinted >= 0 && 5479 assert(CharsPrinted >= 0 &&
5323 (size_t)CharsPrinted < llvm::array_lengthof(buf)); 5480 (size_t)CharsPrinted < llvm::array_lengthof(buf));
5324 (void)CharsPrinted; // avoid warnings if asserts are disabled 5481 (void)CharsPrinted; // avoid warnings if asserts are disabled
5325 Const->emitPoolLabel(Str); 5482 Const->emitPoolLabel(Str);
5326 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " 5483 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
5327 << Value << "\n"; 5484 << Value << "\n";
5328 } 5485 }
5329 } 5486 }
5330 5487
5331 void TargetDataX8632::lowerConstants() { 5488 void TargetDataX8632::lowerConstants() {
5332 if (Ctx->getFlags().getDisableTranslation()) 5489 if (Ctx->getFlags().getDisableTranslation())
5333 return; 5490 return;
5334 // No need to emit constants from the int pool since (for x86) they 5491 // No need to emit constants from the int pool since (for x86) they
5335 // are embedded as immediates in the instructions, just emit float/double. 5492 // are embedded as immediates in the instructions, just emit float/double.
5336 switch (Ctx->getFlags().getOutFileType()) { 5493 switch (Ctx->getFlags().getOutFileType()) {
5337 case FT_Elf: { 5494 case FT_Elf: {
5338 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 5495 ELFObjectWriter *Writer = Ctx->getObjectWriter();
5496
5497 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
5498 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
5499 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
5500
5339 Writer->writeConstantPool<ConstantFloat>(IceType_f32); 5501 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
5340 Writer->writeConstantPool<ConstantDouble>(IceType_f64); 5502 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
5341 } break; 5503 } break;
5342 case FT_Asm: 5504 case FT_Asm:
5343 case FT_Iasm: { 5505 case FT_Iasm: {
5344 OstreamLocker L(Ctx); 5506 OstreamLocker L(Ctx);
5507
5508 emitConstantPool<PoolTypeConverter<char>>(Ctx);
5509 emitConstantPool<PoolTypeConverter<short>>(Ctx);
5510 emitConstantPool<PoolTypeConverter<int>>(Ctx);
5511
5345 emitConstantPool<PoolTypeConverter<float>>(Ctx); 5512 emitConstantPool<PoolTypeConverter<float>>(Ctx);
5346 emitConstantPool<PoolTypeConverter<double>>(Ctx); 5513 emitConstantPool<PoolTypeConverter<double>>(Ctx);
5347 } break; 5514 } break;
5348 } 5515 }
5349 } 5516 }
5350 5517
5351 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) 5518 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
5352 : TargetHeaderLowering(Ctx) {} 5519 : TargetHeaderLowering(Ctx) {}
5353 5520
5521 // Blind/pool an Immediate
5522 Operand *TargetX8632::randomizeOrPoolImmediate(Constant *Immediate,
5523 int32_t RegNum) {
5524 assert(llvm::isa<ConstantInteger32>(Immediate) ||
5525 llvm::isa<ConstantRelocatable>(Immediate));
5526 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5527 RandomizationPoolingPaused == true) {
5528 // immediates randomization/pool turned off
5529 return Immediate;
5530 }
5531 if (Immediate->shouldBeRandomizedOrPooled(Ctx)) {
5532 Ctx->statsUpdateRPImms();
5533 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5534 RPI_Randomize) {
5535 // blind the constant
5536 // FROM:
5537 // imm
5538 // TO:
5539 // insert: mov imm+cookie, Reg
5540 // insert: lea -cookie[Reg], Reg
5541 // => Reg
5542 // If we have already assigned a phy register, we must come from
5543 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5544 // the assigned register as this assignment is that start of its use-def
5545 // chain. So we add RegNum argument here.
5546 Variable *Reg = makeReg(IceType_i32, RegNum);
5547 ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate);
5548 uint32_t Value = Integer->getValue();
5549 uint32_t Cookie = Ctx->getRandomizationCookie();
5550 _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
5551 Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
5552 _lea(Reg,
5553 OperandX8632Mem::create(Func, IceType_i32, Reg, Offset, NULL, 0));
5554 // make sure liveness analysis won't kill this variable, otherwise a
5555 // liveness
5556 // assertion will be triggered.
5557 _set_dest_nonkillable();
5558 if (Immediate->getType() != IceType_i32) {
5559 Variable *TruncReg = makeReg(Immediate->getType(), RegNum);
5560 _mov(TruncReg, Reg);
5561 return TruncReg;
5562 }
5563 return Reg;
5564 }
5565 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5566 // pool the constant
5567 // FROM:
5568 // imm
5569 // TO:
5570 // insert: mov $label, Reg
5571 // => Reg
5572 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool);
5573 Immediate->shouldBePooled = true;
5574 // if we have already assigned a phy register, we must come from
5575 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5576 // the assigned register as this assignment is that start of its use-def
5577 // chain. So we add RegNum argument here.
5578 Variable *Reg = makeReg(Immediate->getType(), RegNum);
5579 IceString Label;
5580 llvm::raw_string_ostream Label_stream(Label);
5581 Immediate->emitPoolLabel(Label_stream);
5582 const RelocOffsetT Offset = 0;
5583 const bool SuppressMangling = true;
5584 Constant *Symbol =
5585 Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
5586 OperandX8632Mem *MemOperand =
5587 OperandX8632Mem::create(Func, Immediate->getType(), NULL, Symbol);
5588 _mov(Reg, MemOperand);
5589 return Reg;
5590 }
5591 assert("Unsupported -randomize-pool-immediates option" && false);
5592 }
5593 // the constant Immediate is not eligible for blinding/pooling
5594 return Immediate;
5595 }
5596
5597 OperandX8632Mem *
5598 TargetX8632::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
5599 int32_t RegNum) {
5600 assert(MemOperand);
5601 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5602 RandomizationPoolingPaused == true) {
5603 // immediates randomization/pooling is turned off
5604 return MemOperand;
5605 }
5606
5607 // If this memory operand is already a randommized one, we do
5608 // not randomize it again.
5609 if (MemOperand->Randomized)
5610 return MemOperand;
qining 2015/06/19 16:23:21 If this memory operand has been randomized, do not
5611
5612 if (Constant *C = llvm::dyn_cast_or_null<Constant>(MemOperand->getOffset())) {
5613 if (C->shouldBeRandomizedOrPooled(Ctx)) {
5614 // The offset of this mem operand should be blinded or pooled
5615 Ctx->statsUpdateRPImms();
5616 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5617 RPI_Randomize) {
5618 // blind the constant offset
5619 // FROM:
5620 // offset[base, index, shift]
5621 // TO:
5622 // insert: lea offset+cookie[base], RegTemp
5623 // => -cookie[RegTemp, index, shift]
5624 uint32_t Value =
5625 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
5626 ->getValue();
5627 uint32_t Cookie = Ctx->getRandomizationCookie();
5628 Constant *Mask1 = Ctx->getConstantInt(
5629 MemOperand->getOffset()->getType(), Cookie + Value);
5630 Constant *Mask2 =
5631 Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
5632
5633 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
5634 Func, MemOperand->getType(), MemOperand->getBase(), Mask1);
5635 // If we have already assigned a physical register, we must come from
5636 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse
5637 // the assigned register as this assignment is that start of its use-def
5638 // chain. So we add RegNum argument here.
5639 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum);
5640 _lea(RegTemp, TempMemOperand);
5641 // As source operand doesn't use the dstreg, we don't need to add
5642 // _set_dest_nonkillable().
5643 // But if we use the same Dest Reg, that is, with RegNum
5644 // assigned, we should add this _set_dest_nonkillable()
5645 if (RegNum != Variable::NoRegister)
5646 _set_dest_nonkillable();
5647
5648 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5649 Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
5650 MemOperand->getShift(), MemOperand->getSegmentRegister());
5651
5652 // Label this memory operand as randomize, so we won't randomize it
5653 // again in case we call legalize() mutiple times on this memory
5654 // operand.
5655 NewMemOperand->Randomized = true;
qining 2015/06/19 16:23:21 label this new memory operand as randomized. This
5656 return NewMemOperand;
5657 }
5658 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5659 // pool the constant offset
5660 // FROM:
5661 // offset[base, index, shift]
5662 // TO:
5663 // insert: mov $label, RegTemp
5664 // insert: lea [base, RegTemp], RegTemp
5665 // =>[RegTemp, index, shift]
5666 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5667 RPI_Pool);
5668 // Memory operand should never exist as source operands in phi
5669 // lowering assignments, so there is no need to reuse any registers
5670 // here. For phi lowering, we should not ask for new physical
5671 // registers in general.
5672 // However, if we do meet Memory Operand during phi lowering, we
5673 // should not blind or pool the immediates for now.
5674 if (RegNum != Variable::NoRegister)
5675 return MemOperand;
5676 Variable *RegTemp = makeReg(IceType_i32);
5677 IceString Label;
5678 llvm::raw_string_ostream Label_stream(Label);
5679 MemOperand->getOffset()->emitPoolLabel(Label_stream);
5680 MemOperand->getOffset()->shouldBePooled = true;
5681 const RelocOffsetT SymOffset = 0;
5682 bool SuppressMangling = true;
5683 Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
5684 SuppressMangling);
5685 OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
5686 Func, MemOperand->getOffset()->getType(), NULL, Symbol);
5687 _mov(RegTemp, SymbolOperand);
5688 // If we have a base variable here, we should add the lea instruction
5689 // to add the value of the base variable to RegTemp. If there is no
5690 // base variable, we won't need this lea instruction.
5691 if (MemOperand->getBase()) {
5692 OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
5693 Func, MemOperand->getType(), MemOperand->getBase(), NULL, RegTemp,
5694 0, MemOperand->getSegmentRegister());
5695 _lea(RegTemp, CalculateOperand);
5696 _set_dest_nonkillable();
5697 }
5698 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5699 Func, MemOperand->getType(), RegTemp, NULL, MemOperand->getIndex(),
5700 MemOperand->getShift(), MemOperand->getSegmentRegister());
5701 return NewMemOperand;
5702 }
5703 assert("Unsupported -randomize-pool-immediates option" && false);
5704 }
5705 }
5706 // the offset is not eligible for blinding or pooling, return the original
5707 // mem operand
5708 return MemOperand;
5709 }
5710
5354 } // end of namespace Ice 5711 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698