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

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

Powered by Google App Engine
This is Rietveld 408576698