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 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 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 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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |