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

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: Fix the default randomization/pooling threshold to be 0xffff 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 has already been handled before");
Jim Stichnoth 2015/06/20 17:42:16 should have
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 From = Ctx->getConstantZero(Ty);
Jim Stichnoth 2015/06/20 17:42:16 I think you need to reset Const as well, e.g.: C
5051 } 5151 }
5052 // There should be no constants of vector type (other than undef). 5152 // There should be no constants of vector type (other than undef).
5053 assert(!isVectorType(Ty)); 5153 assert(!isVectorType(Ty));
5154
5155 // If the operand is an 32 bit constant integer, we should check
5156 // whether we need to randomize it or pool it.
5157 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) {
5158 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum);
5159 if (NewConst != Const) {
5160 return NewConst;
5161 }
5162 }
5163
5054 // Convert a scalar floating point constant into an explicit 5164 // Convert a scalar floating point constant into an explicit
5055 // memory operand. 5165 // memory operand.
5056 if (isScalarFloatingType(Ty)) { 5166 if (isScalarFloatingType(Ty)) {
5057 Variable *Base = nullptr; 5167 Variable *Base = nullptr;
5058 std::string Buffer; 5168 std::string Buffer;
5059 llvm::raw_string_ostream StrBuf(Buffer); 5169 llvm::raw_string_ostream StrBuf(Buffer);
5060 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); 5170 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
5171 llvm::cast<Constant>(From)->setShouldBePooled(true);
5061 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); 5172 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
5062 From = OperandX8632Mem::create(Func, Ty, Base, Offset); 5173 From = OperandX8632Mem::create(Func, Ty, Base, Offset);
5063 } 5174 }
5064 bool NeedsReg = false; 5175 bool NeedsReg = false;
5065 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) 5176 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
5066 // Immediate specifically not allowed 5177 // Immediate specifically not allowed
5067 NeedsReg = true; 5178 NeedsReg = true;
5068 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) 5179 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty))
5069 // On x86, FP constants are lowered to mem operands. 5180 // On x86, FP constants are lowered to mem operands.
5070 NeedsReg = true; 5181 NeedsReg = true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5107 bool IsSrc1ImmOrReg = false; 5218 bool IsSrc1ImmOrReg = false;
5108 if (llvm::isa<Constant>(Src1)) { 5219 if (llvm::isa<Constant>(Src1)) {
5109 IsSrc1ImmOrReg = true; 5220 IsSrc1ImmOrReg = true;
5110 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { 5221 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) {
5111 if (Var->hasReg()) 5222 if (Var->hasReg())
5112 IsSrc1ImmOrReg = true; 5223 IsSrc1ImmOrReg = true;
5113 } 5224 }
5114 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); 5225 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg);
5115 } 5226 }
5116 5227
5117 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Operand, Type Ty, 5228 OperandX8632Mem *TargetX8632::formMemoryOperand(Operand *Opnd, Type Ty,
5118 bool DoLegalize) { 5229 bool DoLegalize) {
5119 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); 5230 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Opnd);
5120 // It may be the case that address mode optimization already creates 5231 // It may be the case that address mode optimization already creates
5121 // an OperandX8632Mem, so in that case it wouldn't need another level 5232 // an OperandX8632Mem, so in that case it wouldn't need another level
5122 // of transformation. 5233 // of transformation.
5123 if (!Mem) { 5234 if (!Mem) {
5124 Variable *Base = llvm::dyn_cast<Variable>(Operand); 5235 Variable *Base = llvm::dyn_cast<Variable>(Opnd);
5125 Constant *Offset = llvm::dyn_cast<Constant>(Operand); 5236 Constant *Offset = llvm::dyn_cast<Constant>(Opnd);
5126 assert(Base || Offset); 5237 assert(Base || Offset);
5127 if (Offset) { 5238 if (Offset) {
5128 // Make sure Offset is not undef. 5239 // During memory operand building, we do not blind or pool
5129 Offset = llvm::cast<Constant>(legalize(Offset)); 5240 // the constant offset, we will work on the whole memory
5241 // operand later as one entity later, this save one instruction.
5242 // By turning blinding and pooling off, we guarantee
5243 // legalize(Offset) will return a constant*.
5244 {
5245 BoolFlagSaver B(RandomizationPoolingPaused, true);
5246
5247 Offset = llvm::cast<Constant>(legalize(Offset));
5248 }
5249
5130 assert(llvm::isa<ConstantInteger32>(Offset) || 5250 assert(llvm::isa<ConstantInteger32>(Offset) ||
5131 llvm::isa<ConstantRelocatable>(Offset)); 5251 llvm::isa<ConstantRelocatable>(Offset));
5132 } 5252 }
5133 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 5253 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
5134 } 5254 }
5135 return llvm::cast<OperandX8632Mem>(DoLegalize ? legalize(Mem) : Mem); 5255 // Do legalization, which contains randomization/pooling
5256 // or do randomization/pooling.
5257 return llvm::cast<OperandX8632Mem>(
5258 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
5136 } 5259 }
5137 5260
5138 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 5261 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
5139 // There aren't any 64-bit integer registers for x86-32. 5262 // There aren't any 64-bit integer registers for x86-32.
5140 assert(Type != IceType_i64); 5263 assert(Type != IceType_i64);
5141 Variable *Reg = Func->makeVariable(Type); 5264 Variable *Reg = Func->makeVariable(Type);
5142 if (RegNum == Variable::NoRegister) 5265 if (RegNum == Variable::NoRegister)
5143 Reg->setWeightInfinite(); 5266 Reg->setWeightInfinite();
5144 else 5267 else
5145 Reg->setRegNum(RegNum); 5268 Reg->setRegNum(RegNum);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
5290 typedef ConstantDouble IceType; 5413 typedef ConstantDouble IceType;
5291 static const Type Ty = IceType_f64; 5414 static const Type Ty = IceType_f64;
5292 static const char *TypeName; 5415 static const char *TypeName;
5293 static const char *AsmTag; 5416 static const char *AsmTag;
5294 static const char *PrintfString; 5417 static const char *PrintfString;
5295 }; 5418 };
5296 const char *PoolTypeConverter<double>::TypeName = "double"; 5419 const char *PoolTypeConverter<double>::TypeName = "double";
5297 const char *PoolTypeConverter<double>::AsmTag = ".quad"; 5420 const char *PoolTypeConverter<double>::AsmTag = ".quad";
5298 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; 5421 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
5299 5422
5423 // Add converter for int type constant pooling
5424 template <> struct PoolTypeConverter<uint32_t> {
5425 typedef uint32_t PrimitiveIntType;
5426 typedef ConstantInteger32 IceType;
5427 static const Type Ty = IceType_i32;
5428 static const char *TypeName;
5429 static const char *AsmTag;
5430 static const char *PrintfString;
5431 };
5432 const char *PoolTypeConverter<uint32_t>::TypeName = "i32";
5433 const char *PoolTypeConverter<uint32_t>::AsmTag = ".long";
5434 const char *PoolTypeConverter<uint32_t>::PrintfString = "0x%x";
5435
5436 // Add converter for int type constant pooling
5437 template <> struct PoolTypeConverter<uint16_t> {
5438 typedef uint32_t PrimitiveIntType;
5439 typedef ConstantInteger32 IceType;
5440 static const Type Ty = IceType_i16;
5441 static const char *TypeName;
5442 static const char *AsmTag;
5443 static const char *PrintfString;
5444 };
5445 const char *PoolTypeConverter<uint16_t>::TypeName = "i16";
5446 const char *PoolTypeConverter<uint16_t>::AsmTag = ".short";
5447 const char *PoolTypeConverter<uint16_t>::PrintfString = "0x%x";
5448
5449 // Add converter for int type constant pooling
5450 template <> struct PoolTypeConverter<uint8_t> {
5451 typedef uint32_t PrimitiveIntType;
5452 typedef ConstantInteger32 IceType;
5453 static const Type Ty = IceType_i8;
5454 static const char *TypeName;
5455 static const char *AsmTag;
5456 static const char *PrintfString;
5457 };
5458 const char *PoolTypeConverter<uint8_t>::TypeName = "i8";
5459 const char *PoolTypeConverter<uint8_t>::AsmTag = ".byte";
5460 const char *PoolTypeConverter<uint8_t>::PrintfString = "0x%x";
5461
5300 template <typename T> 5462 template <typename T>
5301 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) { 5463 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
5302 if (!ALLOW_DUMP) 5464 if (!ALLOW_DUMP)
5303 return; 5465 return;
5304 Ostream &Str = Ctx->getStrEmit(); 5466 Ostream &Str = Ctx->getStrEmit();
5305 Type Ty = T::Ty; 5467 Type Ty = T::Ty;
5306 SizeT Align = typeAlignInBytes(Ty); 5468 SizeT Align = typeAlignInBytes(Ty);
5307 ConstantList Pool = Ctx->getConstantPool(Ty); 5469 ConstantList Pool = Ctx->getConstantPool(Ty);
5308 5470
5309 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 5471 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
5310 << "\n"; 5472 << "\n";
5311 Str << "\t.align\t" << Align << "\n"; 5473 Str << "\t.align\t" << Align << "\n";
5312 for (Constant *C : Pool) { 5474 for (Constant *C : Pool) {
5475 if (!C->getShouldBePooled())
5476 continue;
5313 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); 5477 typename T::IceType *Const = llvm::cast<typename T::IceType>(C);
5314 typename T::IceType::PrimType Value = Const->getValue(); 5478 typename T::IceType::PrimType Value = Const->getValue();
5315 // Use memcpy() to copy bits from Value into RawValue in a way 5479 // Use memcpy() to copy bits from Value into RawValue in a way
5316 // that avoids breaking strict-aliasing rules. 5480 // that avoids breaking strict-aliasing rules.
5317 typename T::PrimitiveIntType RawValue; 5481 typename T::PrimitiveIntType RawValue;
5318 memcpy(&RawValue, &Value, sizeof(Value)); 5482 memcpy(&RawValue, &Value, sizeof(Value));
5319 char buf[30]; 5483 char buf[30];
5320 int CharsPrinted = 5484 int CharsPrinted =
5321 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 5485 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
5322 assert(CharsPrinted >= 0 && 5486 assert(CharsPrinted >= 0 &&
5323 (size_t)CharsPrinted < llvm::array_lengthof(buf)); 5487 (size_t)CharsPrinted < llvm::array_lengthof(buf));
5324 (void)CharsPrinted; // avoid warnings if asserts are disabled 5488 (void)CharsPrinted; // avoid warnings if asserts are disabled
5325 Const->emitPoolLabel(Str); 5489 Const->emitPoolLabel(Str);
5326 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " 5490 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
5327 << Value << "\n"; 5491 << Value << "\n";
5328 } 5492 }
5329 } 5493 }
5330 5494
5331 void TargetDataX8632::lowerConstants() { 5495 void TargetDataX8632::lowerConstants() {
5332 if (Ctx->getFlags().getDisableTranslation()) 5496 if (Ctx->getFlags().getDisableTranslation())
5333 return; 5497 return;
5334 // No need to emit constants from the int pool since (for x86) they 5498 // 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. 5499 // are embedded as immediates in the instructions, just emit float/double.
5336 switch (Ctx->getFlags().getOutFileType()) { 5500 switch (Ctx->getFlags().getOutFileType()) {
5337 case FT_Elf: { 5501 case FT_Elf: {
5338 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 5502 ELFObjectWriter *Writer = Ctx->getObjectWriter();
5503
5504 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
5505 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
5506 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
5507
5339 Writer->writeConstantPool<ConstantFloat>(IceType_f32); 5508 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
5340 Writer->writeConstantPool<ConstantDouble>(IceType_f64); 5509 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
5341 } break; 5510 } break;
5342 case FT_Asm: 5511 case FT_Asm:
5343 case FT_Iasm: { 5512 case FT_Iasm: {
5344 OstreamLocker L(Ctx); 5513 OstreamLocker L(Ctx);
5514
5515 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx);
5516 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx);
5517 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx);
5518
5345 emitConstantPool<PoolTypeConverter<float>>(Ctx); 5519 emitConstantPool<PoolTypeConverter<float>>(Ctx);
5346 emitConstantPool<PoolTypeConverter<double>>(Ctx); 5520 emitConstantPool<PoolTypeConverter<double>>(Ctx);
5347 } break; 5521 } break;
5348 } 5522 }
5349 } 5523 }
5350 5524
5351 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) 5525 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
5352 : TargetHeaderLowering(Ctx) {} 5526 : TargetHeaderLowering(Ctx) {}
5353 5527
5528 // Randomize or pool an Immediate.
5529 Operand *TargetX8632::randomizeOrPoolImmediate(Constant *Immediate,
5530 int32_t RegNum) {
5531 assert(llvm::isa<ConstantInteger32>(Immediate) ||
5532 llvm::isa<ConstantRelocatable>(Immediate));
5533 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5534 RandomizationPoolingPaused == true) {
5535 // Immediates randomization/pooling off or paused
5536 return Immediate;
5537 }
5538 if (Immediate->shouldBeRandomizedOrPooled(Ctx)) {
5539 Ctx->statsUpdateRPImms();
5540 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5541 RPI_Randomize) {
5542 // blind the constant
5543 // FROM:
5544 // imm
5545 // TO:
5546 // insert: mov imm+cookie, Reg
5547 // insert: lea -cookie[Reg], Reg
5548 // => Reg
5549 // If we have already assigned a phy register, we must come from
5550 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5551 // the assigned register as this assignment is that start of its use-def
5552 // chain. So we add RegNum argument here.
5553 // Note we use 'lea' instruction instead of 'xor' to avoid affecting
5554 // the flags.
5555 Variable *Reg = makeReg(IceType_i32, RegNum);
5556 ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate);
5557 uint32_t Value = Integer->getValue();
5558 uint32_t Cookie = Ctx->getRandomizationCookie();
5559 _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
5560 Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
5561 _lea(Reg,
5562 OperandX8632Mem::create(Func, IceType_i32, Reg, Offset, nullptr, 0));
5563 // make sure liveness analysis won't kill this variable, otherwise a
5564 // liveness
5565 // assertion will be triggered.
5566 _set_dest_nonkillable();
5567 if (Immediate->getType() != IceType_i32) {
5568 Variable *TruncReg = makeReg(Immediate->getType(), RegNum);
5569 _mov(TruncReg, Reg);
5570 return TruncReg;
5571 }
5572 return Reg;
5573 }
5574 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5575 // pool the constant
5576 // FROM:
5577 // imm
5578 // TO:
5579 // insert: mov $label, Reg
5580 // => Reg
5581 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool);
5582 Immediate->setShouldBePooled(true);
5583 // if we have already assigned a phy register, we must come from
5584 // andvancedPhiLowering()=>lowerAssign(). In this case we should reuse
5585 // the assigned register as this assignment is that start of its use-def
5586 // chain. So we add RegNum argument here.
5587 Variable *Reg = makeReg(Immediate->getType(), RegNum);
5588 IceString Label;
5589 llvm::raw_string_ostream Label_stream(Label);
5590 Immediate->emitPoolLabel(Label_stream);
5591 const RelocOffsetT Offset = 0;
5592 const bool SuppressMangling = true;
5593 Constant *Symbol =
5594 Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
5595 OperandX8632Mem *MemOperand =
5596 OperandX8632Mem::create(Func, Immediate->getType(), nullptr, Symbol);
5597 _mov(Reg, MemOperand);
5598 return Reg;
5599 }
5600 assert("Unsupported -randomize-pool-immediates option" && false);
5601 }
5602 // the constant Immediate is not eligible for blinding/pooling
5603 return Immediate;
5604 }
5605
5606 OperandX8632Mem *
5607 TargetX8632::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
5608 int32_t RegNum) {
5609 assert(MemOperand);
5610 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
5611 RandomizationPoolingPaused == true) {
5612 // immediates randomization/pooling is turned off
5613 return MemOperand;
5614 }
5615
5616 // If this memory operand is already a randommized one, we do
5617 // not randomize it again.
5618 if (MemOperand->getRandomize())
5619 return MemOperand;
5620
5621 if (Constant *C = llvm::dyn_cast_or_null<Constant>(MemOperand->getOffset())) {
5622 if (C->shouldBeRandomizedOrPooled(Ctx)) {
5623 // The offset of this mem operand should be blinded or pooled
5624 Ctx->statsUpdateRPImms();
5625 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5626 RPI_Randomize) {
5627 // blind the constant offset
5628 // FROM:
5629 // offset[base, index, shift]
5630 // TO:
5631 // insert: lea offset+cookie[base], RegTemp
5632 // => -cookie[RegTemp, index, shift]
5633 uint32_t Value =
5634 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
5635 ->getValue();
5636 uint32_t Cookie = Ctx->getRandomizationCookie();
5637 Constant *Mask1 = Ctx->getConstantInt(
5638 MemOperand->getOffset()->getType(), Cookie + Value);
5639 Constant *Mask2 =
5640 Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
5641
5642 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
5643 Func, MemOperand->getType(), MemOperand->getBase(), Mask1);
5644 // If we have already assigned a physical register, we must come from
5645 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse
5646 // the assigned register as this assignment is that start of its use-def
5647 // chain. So we add RegNum argument here.
5648 Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum);
5649 _lea(RegTemp, TempMemOperand);
5650 // As source operand doesn't use the dstreg, we don't need to add
5651 // _set_dest_nonkillable().
5652 // But if we use the same Dest Reg, that is, with RegNum
5653 // assigned, we should add this _set_dest_nonkillable()
5654 if (RegNum != Variable::NoRegister)
5655 _set_dest_nonkillable();
5656
5657 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5658 Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
5659 MemOperand->getShift(), MemOperand->getSegmentRegister());
5660
5661 // Label this memory operand as randomize, so we won't randomize it
5662 // again in case we call legalize() mutiple times on this memory
5663 // operand.
5664 NewMemOperand->setRandomized(true);
5665 return NewMemOperand;
5666 }
5667 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool) {
5668 // pool the constant offset
5669 // FROM:
5670 // offset[base, index, shift]
5671 // TO:
5672 // insert: mov $label, RegTemp
5673 // insert: lea [base, RegTemp], RegTemp
5674 // =>[RegTemp, index, shift]
5675 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() ==
5676 RPI_Pool);
5677 // Memory operand should never exist as source operands in phi
5678 // lowering assignments, so there is no need to reuse any registers
5679 // here. For phi lowering, we should not ask for new physical
5680 // registers in general.
5681 // However, if we do meet Memory Operand during phi lowering, we
5682 // should not blind or pool the immediates for now.
5683 if (RegNum != Variable::NoRegister)
5684 return MemOperand;
5685 Variable *RegTemp = makeReg(IceType_i32);
5686 IceString Label;
5687 llvm::raw_string_ostream Label_stream(Label);
5688 MemOperand->getOffset()->emitPoolLabel(Label_stream);
5689 MemOperand->getOffset()->setShouldBePooled(true);
5690 const RelocOffsetT SymOffset = 0;
5691 bool SuppressMangling = true;
5692 Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
5693 SuppressMangling);
5694 OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
5695 Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
5696 _mov(RegTemp, SymbolOperand);
5697 // If we have a base variable here, we should add the lea instruction
5698 // to add the value of the base variable to RegTemp. If there is no
5699 // base variable, we won't need this lea instruction.
5700 if (MemOperand->getBase()) {
5701 OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
5702 Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
5703 RegTemp, 0, MemOperand->getSegmentRegister());
5704 _lea(RegTemp, CalculateOperand);
5705 _set_dest_nonkillable();
5706 }
5707 OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
5708 Func, MemOperand->getType(), RegTemp, nullptr,
5709 MemOperand->getIndex(), MemOperand->getShift(),
5710 MemOperand->getSegmentRegister());
5711 return NewMemOperand;
5712 }
5713 assert("Unsupported -randomize-pool-immediates option" && false);
5714 }
5715 }
5716 // the offset is not eligible for blinding or pooling, return the original
5717 // mem operand
5718 return MemOperand;
5719 }
5720
5354 } // end of namespace Ice 5721 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698