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