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

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1848303003: Simplify references to command line flags. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX8664Traits.h ('k') | src/IceTranslator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==//
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 /// \file 10 /// \file
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 } 345 }
346 346
347 template <typename TraitsType> 347 template <typename TraitsType>
348 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func) 348 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func)
349 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) { 349 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) {
350 static_assert( 350 static_assert(
351 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) == 351 (Traits::InstructionSet::End - Traits::InstructionSet::Begin) ==
352 (TargetInstructionSet::X86InstructionSet_End - 352 (TargetInstructionSet::X86InstructionSet_End -
353 TargetInstructionSet::X86InstructionSet_Begin), 353 TargetInstructionSet::X86InstructionSet_Begin),
354 "Traits::InstructionSet range different from TargetInstructionSet"); 354 "Traits::InstructionSet range different from TargetInstructionSet");
355 if (Func->getContext()->getFlags().getTargetInstructionSet() != 355 if (getFlags().getTargetInstructionSet() !=
356 TargetInstructionSet::BaseInstructionSet) { 356 TargetInstructionSet::BaseInstructionSet) {
357 InstructionSet = static_cast<InstructionSetEnum>( 357 InstructionSet = static_cast<InstructionSetEnum>(
358 (Func->getContext()->getFlags().getTargetInstructionSet() - 358 (getFlags().getTargetInstructionSet() -
359 TargetInstructionSet::X86InstructionSet_Begin) + 359 TargetInstructionSet::X86InstructionSet_Begin) +
360 Traits::InstructionSet::Begin); 360 Traits::InstructionSet::Begin);
361 } 361 }
362 } 362 }
363 363
364 template <typename TraitsType> 364 template <typename TraitsType>
365 void TargetX86Base<TraitsType>::staticInit(GlobalContext *Ctx) { 365 void TargetX86Base<TraitsType>::staticInit(GlobalContext *Ctx) {
366 RegNumT::setLimit(Traits::RegisterSet::Reg_NUM); 366 RegNumT::setLimit(Traits::RegisterSet::Reg_NUM);
367 Traits::initRegisterSet(Ctx->getFlags(), &TypeToRegisterSet, 367 Traits::initRegisterSet(getFlags(), &TypeToRegisterSet, &RegisterAliases);
368 &RegisterAliases);
369 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i) 368 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i)
370 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; 369 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i];
371 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM, 370 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM,
372 TypeToRegisterSet.data(), TypeToRegisterSet.size(), 371 TypeToRegisterSet.data(), TypeToRegisterSet.size(),
373 Traits::getRegName, getRegClassName); 372 Traits::getRegName, getRegClassName);
374 PcRelFixup = Traits::FK_PcRel; 373 PcRelFixup = Traits::FK_PcRel;
375 AbsFixup = 374 AbsFixup = getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs;
376 Ctx->getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs;
377 } 375 }
378 376
379 template <typename TraitsType> 377 template <typename TraitsType>
380 bool TargetX86Base<TraitsType>::shouldBePooled(const Constant *C) { 378 bool TargetX86Base<TraitsType>::shouldBePooled(const Constant *C) {
381 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(C)) { 379 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(C)) {
382 return !Utils::isPositiveZero(ConstFloat->getValue()); 380 return !Utils::isPositiveZero(ConstFloat->getValue());
383 } 381 }
384 if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(C)) { 382 if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(C)) {
385 return !Utils::isPositiveZero(ConstDouble->getValue()); 383 return !Utils::isPositiveZero(ConstDouble->getValue());
386 } 384 }
387 if (GlobalContext::getFlags().getRandomizeAndPoolImmediatesOption() != 385 if (getFlags().getRandomizeAndPoolImmediatesOption() != RPI_Pool) {
388 RPI_Pool) {
389 return false; 386 return false;
390 } 387 }
391 return C->shouldBeRandomizedOrPooled(); 388 return C->shouldBeRandomizedOrPooled();
392 } 389 }
393 390
394 template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() { 391 template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() {
395 TimerMarker T(TimerStack::TT_O2, Func); 392 TimerMarker T(TimerStack::TT_O2, Func);
396 393
397 if (SandboxingType != ST_None) { 394 if (SandboxingType != ST_None) {
398 initRebasePtr(); 395 initRebasePtr();
399 } 396 }
400 397
401 genTargetHelperCalls(); 398 genTargetHelperCalls();
402 Func->dump("After target helper call insertion"); 399 Func->dump("After target helper call insertion");
403 400
404 // Merge Alloca instructions, and lay out the stack. 401 // Merge Alloca instructions, and lay out the stack.
405 static constexpr bool SortAndCombineAllocas = true; 402 static constexpr bool SortAndCombineAllocas = true;
406 Func->processAllocas(SortAndCombineAllocas); 403 Func->processAllocas(SortAndCombineAllocas);
407 Func->dump("After Alloca processing"); 404 Func->dump("After Alloca processing");
408 405
409 if (!Ctx->getFlags().getEnablePhiEdgeSplit()) { 406 if (!getFlags().getEnablePhiEdgeSplit()) {
410 // Lower Phi instructions. 407 // Lower Phi instructions.
411 Func->placePhiLoads(); 408 Func->placePhiLoads();
412 if (Func->hasError()) 409 if (Func->hasError())
413 return; 410 return;
414 Func->placePhiStores(); 411 Func->placePhiStores();
415 if (Func->hasError()) 412 if (Func->hasError())
416 return; 413 return;
417 Func->deletePhis(); 414 Func->deletePhis();
418 if (Func->hasError()) 415 if (Func->hasError())
419 return; 416 return;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 assert(Func->validateLiveness()); 482 assert(Func->validateLiveness());
486 // The post-codegen dump is done here, after liveness analysis and associated 483 // The post-codegen dump is done here, after liveness analysis and associated
487 // cleanup, to make the dump cleaner and more useful. 484 // cleanup, to make the dump cleaner and more useful.
488 Func->dump("After initial x8632 codegen"); 485 Func->dump("After initial x8632 codegen");
489 Func->getVMetadata()->init(VMK_All); 486 Func->getVMetadata()->init(VMK_All);
490 regAlloc(RAK_Global); 487 regAlloc(RAK_Global);
491 if (Func->hasError()) 488 if (Func->hasError())
492 return; 489 return;
493 Func->dump("After linear scan regalloc"); 490 Func->dump("After linear scan regalloc");
494 491
495 if (Ctx->getFlags().getEnablePhiEdgeSplit()) { 492 if (getFlags().getEnablePhiEdgeSplit()) {
496 Func->advancedPhiLowering(); 493 Func->advancedPhiLowering();
497 Func->dump("After advanced Phi lowering"); 494 Func->dump("After advanced Phi lowering");
498 } 495 }
499 496
500 // Stack frame mapping. 497 // Stack frame mapping.
501 Func->genFrame(); 498 Func->genFrame();
502 if (Func->hasError()) 499 if (Func->hasError())
503 return; 500 return;
504 Func->dump("After stack frame mapping"); 501 Func->dump("After stack frame mapping");
505 502
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 ") has no register assigned - function " + 890 ") has no register assigned - function " +
894 Func->getFunctionName()); 891 Func->getFunctionName());
895 } 892 }
896 const int32_t Offset = Var->getStackOffset(); 893 const int32_t Offset = Var->getStackOffset();
897 auto BaseRegNum = Var->getBaseRegNum(); 894 auto BaseRegNum = Var->getBaseRegNum();
898 if (BaseRegNum.hasNoValue()) 895 if (BaseRegNum.hasNoValue())
899 BaseRegNum = getFrameOrStackReg(); 896 BaseRegNum = getFrameOrStackReg();
900 // Print in the form "Offset(%reg)", taking care that: 897 // Print in the form "Offset(%reg)", taking care that:
901 // - Offset is never printed when it is 0 898 // - Offset is never printed when it is 0
902 899
903 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); 900 const bool DecorateAsm = getFlags().getDecorateAsm();
904 // Only print Offset when it is nonzero, regardless of DecorateAsm. 901 // Only print Offset when it is nonzero, regardless of DecorateAsm.
905 if (Offset) { 902 if (Offset) {
906 if (DecorateAsm) { 903 if (DecorateAsm) {
907 Str << Var->getSymbolicStackOffset(Func); 904 Str << Var->getSymbolicStackOffset(Func);
908 } else { 905 } else {
909 Str << Offset; 906 Str << Offset;
910 } 907 }
911 } 908 }
912 const Type FrameSPTy = Traits::WordType; 909 const Type FrameSPTy = Traits::WordType;
913 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; 910 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 return legalize(MemOperand); 1369 return legalize(MemOperand);
1373 } 1370 }
1374 llvm_unreachable("Unsupported operand type"); 1371 llvm_unreachable("Unsupported operand type");
1375 return nullptr; 1372 return nullptr;
1376 } 1373 }
1377 1374
1378 template <typename TraitsType> 1375 template <typename TraitsType>
1379 SmallBitVector 1376 SmallBitVector
1380 TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include, 1377 TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include,
1381 RegSetMask Exclude) const { 1378 RegSetMask Exclude) const {
1382 return Traits::getRegisterSet(Ctx->getFlags(), Include, Exclude); 1379 return Traits::getRegisterSet(getFlags(), Include, Exclude);
1383 } 1380 }
1384 1381
1385 template <typename TraitsType> 1382 template <typename TraitsType>
1386 void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Instr) { 1383 void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Instr) {
1387 // Conservatively require the stack to be aligned. Some stack adjustment 1384 // Conservatively require the stack to be aligned. Some stack adjustment
1388 // operations implemented below assume that the stack is aligned before the 1385 // operations implemented below assume that the stack is aligned before the
1389 // alloca. All the alloca code ensures that the stack alignment is preserved 1386 // alloca. All the alloca code ensures that the stack alignment is preserved
1390 // after the alloca. The stack alignment restriction can be relaxed in some 1387 // after the alloca. The stack alignment restriction can be relaxed in some
1391 // cases. 1388 // cases.
1392 NeedsStackAlignment = true; 1389 NeedsStackAlignment = true;
1393 1390
1394 // For default align=0, set it to the real value 1, to avoid any 1391 // For default align=0, set it to the real value 1, to avoid any
1395 // bit-manipulation problems below. 1392 // bit-manipulation problems below.
1396 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes()); 1393 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes());
1397 1394
1398 // LLVM enforces power of 2 alignment. 1395 // LLVM enforces power of 2 alignment.
1399 assert(llvm::isPowerOf2_32(AlignmentParam)); 1396 assert(llvm::isPowerOf2_32(AlignmentParam));
1400 assert(llvm::isPowerOf2_32(Traits::X86_STACK_ALIGNMENT_BYTES)); 1397 assert(llvm::isPowerOf2_32(Traits::X86_STACK_ALIGNMENT_BYTES));
1401 1398
1402 const uint32_t Alignment = 1399 const uint32_t Alignment =
1403 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES); 1400 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES);
1404 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES; 1401 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES;
1405 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; 1402 const bool OptM1 = getFlags().getOptLevel() == Opt_m1;
1406 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset(); 1403 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset();
1407 const bool UseFramePointer = 1404 const bool UseFramePointer =
1408 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; 1405 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1;
1409 1406
1410 if (UseFramePointer) 1407 if (UseFramePointer)
1411 setHasFramePointer(); 1408 setHasFramePointer();
1412 1409
1413 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); 1410 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType);
1414 if (OverAligned) { 1411 if (OverAligned) {
1415 _and(esp, Ctx->getConstantInt32(-Alignment)); 1412 _and(esp, Ctx->getConstantInt32(-Alignment));
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 /// Strength-reduce scalar integer multiplication by a constant (for i32 or 1522 /// Strength-reduce scalar integer multiplication by a constant (for i32 or
1526 /// narrower) for certain constants. The lea instruction can be used to multiply 1523 /// narrower) for certain constants. The lea instruction can be used to multiply
1527 /// by 3, 5, or 9, and the lsh instruction can be used to multiply by powers of 1524 /// by 3, 5, or 9, and the lsh instruction can be used to multiply by powers of
1528 /// 2. These can be combined such that e.g. multiplying by 100 can be done as 2 1525 /// 2. These can be combined such that e.g. multiplying by 100 can be done as 2
1529 /// lea-based multiplies by 5, combined with left-shifting by 2. 1526 /// lea-based multiplies by 5, combined with left-shifting by 2.
1530 template <typename TraitsType> 1527 template <typename TraitsType>
1531 bool TargetX86Base<TraitsType>::optimizeScalarMul(Variable *Dest, Operand *Src0, 1528 bool TargetX86Base<TraitsType>::optimizeScalarMul(Variable *Dest, Operand *Src0,
1532 int32_t Src1) { 1529 int32_t Src1) {
1533 // Disable this optimization for Om1 and O0, just to keep things simple 1530 // Disable this optimization for Om1 and O0, just to keep things simple
1534 // there. 1531 // there.
1535 if (Ctx->getFlags().getOptLevel() < Opt_1) 1532 if (getFlags().getOptLevel() < Opt_1)
1536 return false; 1533 return false;
1537 Type Ty = Dest->getType(); 1534 Type Ty = Dest->getType();
1538 if (Src1 == -1) { 1535 if (Src1 == -1) {
1539 Variable *T = nullptr; 1536 Variable *T = nullptr;
1540 _mov(T, Src0); 1537 _mov(T, Src0);
1541 _neg(T); 1538 _neg(T);
1542 _mov(Dest, T); 1539 _mov(Dest, T);
1543 return true; 1540 return true;
1544 } 1541 }
1545 if (Src1 == 0) { 1542 if (Src1 == 0) {
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 } 2216 }
2220 T_edx = makeReg(Ty, Edx); 2217 T_edx = makeReg(Ty, Edx);
2221 _mov(T, Src0, Eax); 2218 _mov(T, Src0, Eax);
2222 _mov(T_edx, Ctx->getConstantZero(Ty)); 2219 _mov(T_edx, Ctx->getConstantZero(Ty));
2223 _div(T, Src1, T_edx); 2220 _div(T, Src1, T_edx);
2224 _mov(Dest, T); 2221 _mov(Dest, T);
2225 } break; 2222 } break;
2226 case InstArithmetic::Sdiv: 2223 case InstArithmetic::Sdiv:
2227 // TODO(stichnot): Enable this after doing better performance and cross 2224 // TODO(stichnot): Enable this after doing better performance and cross
2228 // testing. 2225 // testing.
2229 if (false && Ctx->getFlags().getOptLevel() >= Opt_1) { 2226 if (false && getFlags().getOptLevel() >= Opt_1) {
2230 // Optimize division by constant power of 2, but not for Om1 or O0, just 2227 // Optimize division by constant power of 2, but not for Om1 or O0, just
2231 // to keep things simple there. 2228 // to keep things simple there.
2232 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) { 2229 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
2233 const int32_t Divisor = C->getValue(); 2230 const int32_t Divisor = C->getValue();
2234 const uint32_t UDivisor = Divisor; 2231 const uint32_t UDivisor = Divisor;
2235 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) { 2232 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) {
2236 uint32_t LogDiv = llvm::Log2_32(UDivisor); 2233 uint32_t LogDiv = llvm::Log2_32(UDivisor);
2237 // LLVM does the following for dest=src/(1<<log): 2234 // LLVM does the following for dest=src/(1<<log):
2238 // t=src 2235 // t=src
2239 // sar t,typewidth-1 // -1 if src is negative, 0 if not 2236 // sar t,typewidth-1 // -1 if src is negative, 0 if not
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2309 } 2306 }
2310 T_edx = makeReg(Ty, Edx); 2307 T_edx = makeReg(Ty, Edx);
2311 _mov(T_edx, Ctx->getConstantZero(Ty)); 2308 _mov(T_edx, Ctx->getConstantZero(Ty));
2312 _mov(T, Src0, Eax); 2309 _mov(T, Src0, Eax);
2313 _div(T_edx, Src1, T); 2310 _div(T_edx, Src1, T);
2314 _mov(Dest, T_edx); 2311 _mov(Dest, T_edx);
2315 } break; 2312 } break;
2316 case InstArithmetic::Srem: { 2313 case InstArithmetic::Srem: {
2317 // TODO(stichnot): Enable this after doing better performance and cross 2314 // TODO(stichnot): Enable this after doing better performance and cross
2318 // testing. 2315 // testing.
2319 if (false && Ctx->getFlags().getOptLevel() >= Opt_1) { 2316 if (false && getFlags().getOptLevel() >= Opt_1) {
2320 // Optimize mod by constant power of 2, but not for Om1 or O0, just to 2317 // Optimize mod by constant power of 2, but not for Om1 or O0, just to
2321 // keep things simple there. 2318 // keep things simple there.
2322 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) { 2319 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
2323 const int32_t Divisor = C->getValue(); 2320 const int32_t Divisor = C->getValue();
2324 const uint32_t UDivisor = Divisor; 2321 const uint32_t UDivisor = Divisor;
2325 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) { 2322 if (Divisor > 0 && llvm::isPowerOf2_32(UDivisor)) {
2326 uint32_t LogDiv = llvm::Log2_32(UDivisor); 2323 uint32_t LogDiv = llvm::Log2_32(UDivisor);
2327 // LLVM does the following for dest=src%(1<<log): 2324 // LLVM does the following for dest=src%(1<<log):
2328 // t=src 2325 // t=src
2329 // sar t,typewidth-1 // -1 if src is negative, 0 if not 2326 // sar t,typewidth-1 // -1 if src is negative, 0 if not
(...skipping 1972 matching lines...) Expand 10 before | Expand all | Expand 10 after
4302 constexpr bool Locked = true; 4299 constexpr bool Locked = true;
4303 _cmpxchg(Addr, T_eax, DesiredReg, Locked); 4300 _cmpxchg(Addr, T_eax, DesiredReg, Locked);
4304 _mov(DestPrev, T_eax); 4301 _mov(DestPrev, T_eax);
4305 } 4302 }
4306 4303
4307 template <typename TraitsType> 4304 template <typename TraitsType>
4308 bool TargetX86Base<TraitsType>::tryOptimizedCmpxchgCmpBr(Variable *Dest, 4305 bool TargetX86Base<TraitsType>::tryOptimizedCmpxchgCmpBr(Variable *Dest,
4309 Operand *PtrToMem, 4306 Operand *PtrToMem,
4310 Operand *Expected, 4307 Operand *Expected,
4311 Operand *Desired) { 4308 Operand *Desired) {
4312 if (Ctx->getFlags().getOptLevel() == Opt_m1) 4309 if (getFlags().getOptLevel() == Opt_m1)
4313 return false; 4310 return false;
4314 // Peek ahead a few instructions and see how Dest is used. 4311 // Peek ahead a few instructions and see how Dest is used.
4315 // It's very common to have: 4312 // It's very common to have:
4316 // 4313 //
4317 // %x = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* ptr, i32 %expected, ...) 4314 // %x = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* ptr, i32 %expected, ...)
4318 // [%y_phi = ...] // list of phi stores 4315 // [%y_phi = ...] // list of phi stores
4319 // %p = icmp eq i32 %x, %expected 4316 // %p = icmp eq i32 %x, %expected
4320 // br i1 %p, label %l1, label %l2 4317 // br i1 %p, label %l1, label %l2
4321 // 4318 //
4322 // which we can optimize into: 4319 // which we can optimize into:
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
5272 5269
5273 // If the Base has more than one use or is live across multiple blocks, then 5270 // If the Base has more than one use or is live across multiple blocks, then
5274 // don't go further. Alternatively (?), never consider a transformation that 5271 // don't go further. Alternatively (?), never consider a transformation that
5275 // would change a variable that is currently *not* live across basic block 5272 // would change a variable that is currently *not* live across basic block
5276 // boundaries into one that *is*. 5273 // boundaries into one that *is*.
5277 if (Func->getVMetadata()->isMultiBlock( 5274 if (Func->getVMetadata()->isMultiBlock(
5278 NewAddr.Base) /* || Base->getUseCount() > 1*/) 5275 NewAddr.Base) /* || Base->getUseCount() > 1*/)
5279 return nullptr; 5276 return nullptr;
5280 5277
5281 AddressOptimizer AddrOpt(Func); 5278 AddressOptimizer AddrOpt(Func);
5282 const bool MockBounds = Func->getContext()->getFlags().getMockBoundsCheck(); 5279 const bool MockBounds = getFlags().getMockBoundsCheck();
5283 const Inst *Reason = nullptr; 5280 const Inst *Reason = nullptr;
5284 bool AddressWasOptimized = false; 5281 bool AddressWasOptimized = false;
5285 // The following unnamed struct identifies the address mode formation steps 5282 // The following unnamed struct identifies the address mode formation steps
5286 // that could potentially create an invalid memory operand (i.e., no free 5283 // that could potentially create an invalid memory operand (i.e., no free
5287 // slots for RebasePtr.) We add all those variables to this struct so that we 5284 // slots for RebasePtr.) We add all those variables to this struct so that we
5288 // can use memset() to reset all members to false. 5285 // can use memset() to reset all members to false.
5289 struct { 5286 struct {
5290 bool AssignBase = false; 5287 bool AssignBase = false;
5291 bool AssignIndex = false; 5288 bool AssignIndex = false;
5292 bool OffsetFromBase = false; 5289 bool OffsetFromBase = false;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
5464 /// cmp reg, 0 5461 /// cmp reg, 0
5465 /// je label 5462 /// je label
5466 /// cmp reg, 1 5463 /// cmp reg, 1
5467 /// je label 5464 /// je label
5468 /// label: 5465 /// label:
5469 /// 5466 ///
5470 /// Also note that we don't need to add a bounds check to a dereference of a 5467 /// Also note that we don't need to add a bounds check to a dereference of a
5471 /// simple global variable address. 5468 /// simple global variable address.
5472 template <typename TraitsType> 5469 template <typename TraitsType>
5473 void TargetX86Base<TraitsType>::doMockBoundsCheck(Operand *Opnd) { 5470 void TargetX86Base<TraitsType>::doMockBoundsCheck(Operand *Opnd) {
5474 if (!Ctx->getFlags().getMockBoundsCheck()) 5471 if (!getFlags().getMockBoundsCheck())
5475 return; 5472 return;
5476 if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Opnd)) { 5473 if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Opnd)) {
5477 if (Mem->getIndex()) { 5474 if (Mem->getIndex()) {
5478 llvm::report_fatal_error("doMockBoundsCheck: Opnd contains index reg"); 5475 llvm::report_fatal_error("doMockBoundsCheck: Opnd contains index reg");
5479 } 5476 }
5480 Opnd = Mem->getBase(); 5477 Opnd = Mem->getBase();
5481 } 5478 }
5482 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps 5479 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps
5483 // something else. We only care if it is Variable. 5480 // something else. We only care if it is Variable.
5484 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd); 5481 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd);
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
6184 } else { 6181 } else {
6185 TargetLowering::lowerOther(Instr); 6182 TargetLowering::lowerOther(Instr);
6186 } 6183 }
6187 } 6184 }
6188 6185
6189 /// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve 6186 /// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
6190 /// integrity of liveness analysis. Undef values are also turned into zeroes, 6187 /// integrity of liveness analysis. Undef values are also turned into zeroes,
6191 /// since loOperand() and hiOperand() don't expect Undef input. Also, in 6188 /// since loOperand() and hiOperand() don't expect Undef input. Also, in
6192 /// Non-SFI mode, add a FakeUse(RebasePtr) for every pooled constant operand. 6189 /// Non-SFI mode, add a FakeUse(RebasePtr) for every pooled constant operand.
6193 template <typename TraitsType> void TargetX86Base<TraitsType>::prelowerPhis() { 6190 template <typename TraitsType> void TargetX86Base<TraitsType>::prelowerPhis() {
6194 if (Ctx->getFlags().getUseNonsfi()) { 6191 if (getFlags().getUseNonsfi()) {
6195 assert(RebasePtr); 6192 assert(RebasePtr);
6196 CfgNode *Node = Context.getNode(); 6193 CfgNode *Node = Context.getNode();
6197 uint32_t RebasePtrUseCount = 0; 6194 uint32_t RebasePtrUseCount = 0;
6198 for (Inst &I : Node->getPhis()) { 6195 for (Inst &I : Node->getPhis()) {
6199 auto *Phi = llvm::dyn_cast<InstPhi>(&I); 6196 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
6200 if (Phi->isDeleted()) 6197 if (Phi->isDeleted())
6201 continue; 6198 continue;
6202 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { 6199 for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
6203 Operand *Src = Phi->getSrc(I); 6200 Operand *Src = Phi->getSrc(I);
6204 // TODO(stichnot): This over-counts for +0.0, and under-counts for other 6201 // TODO(stichnot): This over-counts for +0.0, and under-counts for other
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
6711 _movp(Reg, Src); 6708 _movp(Reg, Src);
6712 } else { 6709 } else {
6713 _mov(Reg, Src); 6710 _mov(Reg, Src);
6714 } 6711 }
6715 return Reg; 6712 return Reg;
6716 } 6713 }
6717 6714
6718 template <typename TraitsType> 6715 template <typename TraitsType>
6719 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed, 6716 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed,
6720 RegNumT RegNum) { 6717 RegNumT RegNum) {
6721 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); 6718 const bool UseNonsfi = getFlags().getUseNonsfi();
6722 const Type Ty = From->getType(); 6719 const Type Ty = From->getType();
6723 // Assert that a physical register is allowed. To date, all calls to 6720 // Assert that a physical register is allowed. To date, all calls to
6724 // legalize() allow a physical register. If a physical register needs to be 6721 // legalize() allow a physical register. If a physical register needs to be
6725 // explicitly disallowed, then new code will need to be written to force a 6722 // explicitly disallowed, then new code will need to be written to force a
6726 // spill. 6723 // spill.
6727 assert(Allowed & Legal_Reg); 6724 assert(Allowed & Legal_Reg);
6728 // If we're asking for a specific physical register, make sure we're not 6725 // If we're asking for a specific physical register, make sure we're not
6729 // allowing any other operand kinds. (This could be future work, e.g. allow 6726 // allowing any other operand kinds. (This could be future work, e.g. allow
6730 // the shl shift amount to be either an immediate or in ecx.) 6727 // the shl shift amount to be either an immediate or in ecx.)
6731 assert(RegNum.hasNoValue() || Allowed == Legal_Reg); 6728 assert(RegNum.hasNoValue() || Allowed == Legal_Reg);
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
7008 uint32_t TyIndex = llvm::findLastSet(Size, llvm::ZB_Undefined); 7005 uint32_t TyIndex = llvm::findLastSet(Size, llvm::ZB_Undefined);
7009 if (!llvm::isPowerOf2_32(Size)) 7006 if (!llvm::isPowerOf2_32(Size))
7010 ++TyIndex; 7007 ++TyIndex;
7011 uint32_t MaxIndex = MaxSize == NoSizeLimit 7008 uint32_t MaxIndex = MaxSize == NoSizeLimit
7012 ? llvm::array_lengthof(TypeForSize) - 1 7009 ? llvm::array_lengthof(TypeForSize) - 1
7013 : llvm::findLastSet(MaxSize, llvm::ZB_Undefined); 7010 : llvm::findLastSet(MaxSize, llvm::ZB_Undefined);
7014 return TypeForSize[std::min(TyIndex, MaxIndex)]; 7011 return TypeForSize[std::min(TyIndex, MaxIndex)];
7015 } 7012 }
7016 7013
7017 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() { 7014 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() {
7018 if (Ctx->getFlags().getOptLevel() == Opt_m1) 7015 if (getFlags().getOptLevel() == Opt_m1)
7019 return; 7016 return;
7020 markRedefinitions(); 7017 markRedefinitions();
7021 Context.availabilityUpdate(); 7018 Context.availabilityUpdate();
7022 } 7019 }
7023 7020
7024 template <typename TraitsType> 7021 template <typename TraitsType>
7025 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation( 7022 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation(
7026 llvm::SmallVectorImpl<RegNumT> &Permutation, 7023 llvm::SmallVectorImpl<RegNumT> &Permutation,
7027 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 7024 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
7028 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, 7025 Traits::makeRandomRegisterPermutation(Func, Permutation, ExcludeRegisters,
7029 ExcludeRegisters, Salt); 7026 Salt);
7030 } 7027 }
7031 7028
7032 template <typename TraitsType> 7029 template <typename TraitsType>
7033 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const { 7030 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const {
7034 if (!BuildDefs::dump()) 7031 if (!BuildDefs::dump())
7035 return; 7032 return;
7036 Ostream &Str = Ctx->getStrEmit(); 7033 Ostream &Str = Ctx->getStrEmit();
7037 Str << "$" << C->getValue(); 7034 Str << "$" << C->getValue();
7038 } 7035 }
7039 7036
(...skipping 27 matching lines...) Expand all
7067 7064
7068 template <typename TraitsType> 7065 template <typename TraitsType>
7069 void TargetX86Base<TraitsType>::emit(const ConstantUndef *) const { 7066 void TargetX86Base<TraitsType>::emit(const ConstantUndef *) const {
7070 llvm::report_fatal_error("undef value encountered by emitter."); 7067 llvm::report_fatal_error("undef value encountered by emitter.");
7071 } 7068 }
7072 7069
7073 template <class Machine> 7070 template <class Machine>
7074 void TargetX86Base<Machine>::emit(const ConstantRelocatable *C) const { 7071 void TargetX86Base<Machine>::emit(const ConstantRelocatable *C) const {
7075 if (!BuildDefs::dump()) 7072 if (!BuildDefs::dump())
7076 return; 7073 return;
7077 assert(!Ctx->getFlags().getUseNonsfi() || 7074 assert(!getFlags().getUseNonsfi() ||
7078 C->getName().toString() == GlobalOffsetTable); 7075 C->getName().toString() == GlobalOffsetTable);
7079 Ostream &Str = Ctx->getStrEmit(); 7076 Ostream &Str = Ctx->getStrEmit();
7080 Str << "$"; 7077 Str << "$";
7081 emitWithoutPrefix(C); 7078 emitWithoutPrefix(C);
7082 } 7079 }
7083 7080
7084 /// Randomize or pool an Immediate. 7081 /// Randomize or pool an Immediate.
7085 template <typename TraitsType> 7082 template <typename TraitsType>
7086 Operand * 7083 Operand *
7087 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, 7084 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate,
7088 RegNumT RegNum) { 7085 RegNumT RegNum) {
7089 assert(llvm::isa<ConstantInteger32>(Immediate) || 7086 assert(llvm::isa<ConstantInteger32>(Immediate) ||
7090 llvm::isa<ConstantRelocatable>(Immediate)); 7087 llvm::isa<ConstantRelocatable>(Immediate));
7091 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || 7088 if (getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
7092 RandomizationPoolingPaused == true) { 7089 RandomizationPoolingPaused == true) {
7093 // Immediates randomization/pooling off or paused 7090 // Immediates randomization/pooling off or paused
7094 return Immediate; 7091 return Immediate;
7095 } 7092 }
7096 7093
7097 if (Traits::Is64Bit && NeedSandboxing) { 7094 if (Traits::Is64Bit && NeedSandboxing) {
7098 // Immediate randomization/pooling is currently disabled for x86-64 7095 // Immediate randomization/pooling is currently disabled for x86-64
7099 // sandboxing for it could generate invalid memory operands. 7096 // sandboxing for it could generate invalid memory operands.
7100 assert(false && 7097 assert(false &&
7101 "Constant pooling/randomization is disabled for x8664 sandbox."); 7098 "Constant pooling/randomization is disabled for x8664 sandbox.");
7102 return Immediate; 7099 return Immediate;
7103 } 7100 }
7104 7101
7105 if (!Immediate->shouldBeRandomizedOrPooled()) { 7102 if (!Immediate->shouldBeRandomizedOrPooled()) {
7106 // the constant Immediate is not eligible for blinding/pooling 7103 // the constant Immediate is not eligible for blinding/pooling
7107 return Immediate; 7104 return Immediate;
7108 } 7105 }
7109 Ctx->statsUpdateRPImms(); 7106 Ctx->statsUpdateRPImms();
7110 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { 7107 switch (getFlags().getRandomizeAndPoolImmediatesOption()) {
7111 default: 7108 default:
7112 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); 7109 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option");
7113 case RPI_Randomize: { 7110 case RPI_Randomize: {
7114 // blind the constant 7111 // blind the constant
7115 // FROM: 7112 // FROM:
7116 // imm 7113 // imm
7117 // TO: 7114 // TO:
7118 // insert: mov imm+cookie, Reg 7115 // insert: mov imm+cookie, Reg
7119 // insert: lea -cookie[Reg], Reg 7116 // insert: lea -cookie[Reg], Reg
7120 // => Reg 7117 // => Reg
(...skipping 16 matching lines...) Expand all
7137 _mov(TruncReg, Reg); 7134 _mov(TruncReg, Reg);
7138 return TruncReg; 7135 return TruncReg;
7139 } 7136 }
7140 case RPI_Pool: { 7137 case RPI_Pool: {
7141 // pool the constant 7138 // pool the constant
7142 // FROM: 7139 // FROM:
7143 // imm 7140 // imm
7144 // TO: 7141 // TO:
7145 // insert: mov $label, Reg 7142 // insert: mov $label, Reg
7146 // => Reg 7143 // => Reg
7147 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool); 7144 assert(getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool);
7148 assert(Immediate->getShouldBePooled()); 7145 assert(Immediate->getShouldBePooled());
7149 // if we have already assigned a phy register, we must come from 7146 // if we have already assigned a phy register, we must come from
7150 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse the 7147 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse the
7151 // assigned register as this assignment is that start of its use-def 7148 // assigned register as this assignment is that start of its use-def
7152 // chain. So we add RegNum argument here. 7149 // chain. So we add RegNum argument here.
7153 Variable *Reg = makeReg(Immediate->getType(), RegNum); 7150 Variable *Reg = makeReg(Immediate->getType(), RegNum);
7154 constexpr RelocOffsetT Offset = 0; 7151 constexpr RelocOffsetT Offset = 0;
7155 Constant *Symbol = Ctx->getConstantSym(Offset, Immediate->getLabelName()); 7152 Constant *Symbol = Ctx->getConstantSym(Offset, Immediate->getLabelName());
7156 constexpr Variable *NoBase = nullptr; 7153 constexpr Variable *NoBase = nullptr;
7157 X86OperandMem *MemOperand = 7154 X86OperandMem *MemOperand =
7158 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); 7155 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol);
7159 _mov(Reg, MemOperand); 7156 _mov(Reg, MemOperand);
7160 return Reg; 7157 return Reg;
7161 } 7158 }
7162 } 7159 }
7163 } 7160 }
7164 7161
7165 template <typename TraitsType> 7162 template <typename TraitsType>
7166 typename TargetX86Base<TraitsType>::X86OperandMem * 7163 typename TargetX86Base<TraitsType>::X86OperandMem *
7167 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand, 7164 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand,
7168 RegNumT RegNum) { 7165 RegNumT RegNum) {
7169 assert(MemOperand); 7166 assert(MemOperand);
7170 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || 7167 if (getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
7171 RandomizationPoolingPaused == true) { 7168 RandomizationPoolingPaused == true) {
7172 // immediates randomization/pooling is turned off 7169 // immediates randomization/pooling is turned off
7173 return MemOperand; 7170 return MemOperand;
7174 } 7171 }
7175 7172
7176 if (Traits::Is64Bit && NeedSandboxing) { 7173 if (Traits::Is64Bit && NeedSandboxing) {
7177 // Immediate randomization/pooling is currently disabled for x86-64 7174 // Immediate randomization/pooling is currently disabled for x86-64
7178 // sandboxing for it could generate invalid memory operands. 7175 // sandboxing for it could generate invalid memory operands.
7179 assert(false && 7176 assert(false &&
7180 "Constant pooling/randomization is disabled for x8664 sandbox."); 7177 "Constant pooling/randomization is disabled for x8664 sandbox.");
(...skipping 10 matching lines...) Expand all
7191 if (C == nullptr) { 7188 if (C == nullptr) {
7192 return MemOperand; 7189 return MemOperand;
7193 } 7190 }
7194 7191
7195 if (!C->shouldBeRandomizedOrPooled()) { 7192 if (!C->shouldBeRandomizedOrPooled()) {
7196 return MemOperand; 7193 return MemOperand;
7197 } 7194 }
7198 7195
7199 // The offset of this mem operand should be blinded or pooled 7196 // The offset of this mem operand should be blinded or pooled
7200 Ctx->statsUpdateRPImms(); 7197 Ctx->statsUpdateRPImms();
7201 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { 7198 switch (getFlags().getRandomizeAndPoolImmediatesOption()) {
7202 default: 7199 default:
7203 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); 7200 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option");
7204 case RPI_Randomize: { 7201 case RPI_Randomize: {
7205 // blind the constant offset 7202 // blind the constant offset
7206 // FROM: 7203 // FROM:
7207 // offset[base, index, shift] 7204 // offset[base, index, shift]
7208 // TO: 7205 // TO:
7209 // insert: lea offset+cookie[base], RegTemp 7206 // insert: lea offset+cookie[base], RegTemp
7210 // => -cookie[RegTemp, index, shift] 7207 // => -cookie[RegTemp, index, shift]
7211 uint32_t Value = 7208 uint32_t Value =
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
7277 } 7274 }
7278 } 7275 }
7279 } 7276 }
7280 7277
7281 template <typename TraitsType> 7278 template <typename TraitsType>
7282 void TargetX86Base<TraitsType>::emitJumpTable( 7279 void TargetX86Base<TraitsType>::emitJumpTable(
7283 const Cfg *Func, const InstJumpTable *JumpTable) const { 7280 const Cfg *Func, const InstJumpTable *JumpTable) const {
7284 if (!BuildDefs::dump()) 7281 if (!BuildDefs::dump())
7285 return; 7282 return;
7286 Ostream &Str = Ctx->getStrEmit(); 7283 Ostream &Str = Ctx->getStrEmit();
7287 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); 7284 const bool UseNonsfi = getFlags().getUseNonsfi();
7288 GlobalString FunctionName = Func->getFunctionName(); 7285 GlobalString FunctionName = Func->getFunctionName();
7289 const char *Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; 7286 const char *Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata.";
7290 Str << "\t.section\t" << Prefix << FunctionName 7287 Str << "\t.section\t" << Prefix << FunctionName
7291 << "$jumptable,\"a\",@progbits\n"; 7288 << "$jumptable,\"a\",@progbits\n";
7292 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; 7289 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
7293 Str << InstJumpTable::makeName(FunctionName, JumpTable->getId()) << ":"; 7290 Str << InstJumpTable::makeName(FunctionName, JumpTable->getId()) << ":";
7294 7291
7295 // On X86 ILP32 pointers are 32-bit hence the use of .long 7292 // On X86 ILP32 pointers are 32-bit hence the use of .long
7296 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) 7293 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I)
7297 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); 7294 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName();
7298 Str << "\n"; 7295 Str << "\n";
7299 } 7296 }
7300 7297
7301 template <typename TraitsType> 7298 template <typename TraitsType>
7302 template <typename T> 7299 template <typename T>
7303 void TargetDataX86<TraitsType>::emitConstantPool(GlobalContext *Ctx) { 7300 void TargetDataX86<TraitsType>::emitConstantPool(GlobalContext *Ctx) {
7304 if (!BuildDefs::dump()) 7301 if (!BuildDefs::dump())
7305 return; 7302 return;
7306 Ostream &Str = Ctx->getStrEmit(); 7303 Ostream &Str = Ctx->getStrEmit();
7307 Type Ty = T::Ty; 7304 Type Ty = T::Ty;
7308 SizeT Align = typeAlignInBytes(Ty); 7305 SizeT Align = typeAlignInBytes(Ty);
7309 ConstantList Pool = Ctx->getConstantPool(Ty); 7306 ConstantList Pool = Ctx->getConstantPool(Ty);
7310 7307
7311 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 7308 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
7312 << "\n"; 7309 << "\n";
7313 Str << "\t.align\t" << Align << "\n"; 7310 Str << "\t.align\t" << Align << "\n";
7314 7311
7315 // If reorder-pooled-constants option is set to true, we need to shuffle the 7312 // If reorder-pooled-constants option is set to true, we need to shuffle the
7316 // constant pool before emitting it. 7313 // constant pool before emitting it.
7317 if (Ctx->getFlags().getReorderPooledConstants() && !Pool.empty()) { 7314 if (getFlags().getReorderPooledConstants() && !Pool.empty()) {
7318 // Use the constant's kind value as the salt for creating random number 7315 // Use the constant's kind value as the salt for creating random number
7319 // generator. 7316 // generator.
7320 Operand::OperandKind K = (*Pool.begin())->getKind(); 7317 Operand::OperandKind K = (*Pool.begin())->getKind();
7321 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), 7318 RandomNumberGenerator RNG(getFlags().getRandomSeed(),
7322 RPE_PooledConstantReordering, K); 7319 RPE_PooledConstantReordering, K);
7323 RandomShuffle(Pool.begin(), Pool.end(), 7320 RandomShuffle(Pool.begin(), Pool.end(),
7324 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); 7321 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
7325 } 7322 }
7326 7323
7327 for (Constant *C : Pool) { 7324 for (Constant *C : Pool) {
7328 if (!C->getShouldBePooled()) 7325 if (!C->getShouldBePooled())
7329 continue; 7326 continue;
7330 auto *Const = llvm::cast<typename T::IceType>(C); 7327 auto *Const = llvm::cast<typename T::IceType>(C);
7331 typename T::IceType::PrimType Value = Const->getValue(); 7328 typename T::IceType::PrimType Value = Const->getValue();
7332 // Use memcpy() to copy bits from Value into RawValue in a way that avoids 7329 // Use memcpy() to copy bits from Value into RawValue in a way that avoids
7333 // breaking strict-aliasing rules. 7330 // breaking strict-aliasing rules.
7334 typename T::PrimitiveIntType RawValue; 7331 typename T::PrimitiveIntType RawValue;
7335 memcpy(&RawValue, &Value, sizeof(Value)); 7332 memcpy(&RawValue, &Value, sizeof(Value));
7336 char buf[30]; 7333 char buf[30];
7337 int CharsPrinted = 7334 int CharsPrinted =
7338 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 7335 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
7339 assert(CharsPrinted >= 0); 7336 assert(CharsPrinted >= 0);
7340 assert((size_t)CharsPrinted < llvm::array_lengthof(buf)); 7337 assert((size_t)CharsPrinted < llvm::array_lengthof(buf));
7341 (void)CharsPrinted; // avoid warnings if asserts are disabled 7338 (void)CharsPrinted; // avoid warnings if asserts are disabled
7342 Str << Const->getLabelName(); 7339 Str << Const->getLabelName();
7343 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " " 7340 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " "
7344 << Value << " */\n"; 7341 << Value << " */\n";
7345 } 7342 }
7346 } 7343 }
7347 7344
7348 template <typename TraitsType> 7345 template <typename TraitsType>
7349 void TargetDataX86<TraitsType>::lowerConstants() { 7346 void TargetDataX86<TraitsType>::lowerConstants() {
7350 if (Ctx->getFlags().getDisableTranslation()) 7347 if (getFlags().getDisableTranslation())
7351 return; 7348 return;
7352 switch (Ctx->getFlags().getOutFileType()) { 7349 switch (getFlags().getOutFileType()) {
7353 case FT_Elf: { 7350 case FT_Elf: {
7354 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 7351 ELFObjectWriter *Writer = Ctx->getObjectWriter();
7355 7352
7356 Writer->writeConstantPool<ConstantInteger32>(IceType_i8); 7353 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
7357 Writer->writeConstantPool<ConstantInteger32>(IceType_i16); 7354 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
7358 Writer->writeConstantPool<ConstantInteger32>(IceType_i32); 7355 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
7359 7356
7360 Writer->writeConstantPool<ConstantFloat>(IceType_f32); 7357 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
7361 Writer->writeConstantPool<ConstantDouble>(IceType_f64); 7358 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
7362 } break; 7359 } break;
7363 case FT_Asm: 7360 case FT_Asm:
7364 case FT_Iasm: { 7361 case FT_Iasm: {
7365 OstreamLocker L(Ctx); 7362 OstreamLocker L(Ctx);
7366 7363
7367 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx); 7364 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx);
7368 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); 7365 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx);
7369 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); 7366 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx);
7370 7367
7371 emitConstantPool<PoolTypeConverter<float>>(Ctx); 7368 emitConstantPool<PoolTypeConverter<float>>(Ctx);
7372 emitConstantPool<PoolTypeConverter<double>>(Ctx); 7369 emitConstantPool<PoolTypeConverter<double>>(Ctx);
7373 } break; 7370 } break;
7374 } 7371 }
7375 } 7372 }
7376 7373
7377 template <typename TraitsType> 7374 template <typename TraitsType>
7378 void TargetDataX86<TraitsType>::lowerJumpTables() { 7375 void TargetDataX86<TraitsType>::lowerJumpTables() {
7379 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); 7376 const bool IsPIC = getFlags().getUseNonsfi();
7380 switch (Ctx->getFlags().getOutFileType()) { 7377 switch (getFlags().getOutFileType()) {
7381 case FT_Elf: { 7378 case FT_Elf: {
7382 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 7379 ELFObjectWriter *Writer = Ctx->getObjectWriter();
7383 for (const JumpTableData &JT : Ctx->getJumpTables()) 7380 for (const JumpTableData &JT : Ctx->getJumpTables())
7384 Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC); 7381 Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC);
7385 } break; 7382 } break;
7386 case FT_Asm: 7383 case FT_Asm:
7387 // Already emitted from Cfg 7384 // Already emitted from Cfg
7388 break; 7385 break;
7389 case FT_Iasm: { 7386 case FT_Iasm: {
7390 if (!BuildDefs::dump()) 7387 if (!BuildDefs::dump())
(...skipping 11 matching lines...) Expand all
7402 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; 7399 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset;
7403 Str << "\n"; 7400 Str << "\n";
7404 } 7401 }
7405 } break; 7402 } break;
7406 } 7403 }
7407 } 7404 }
7408 7405
7409 template <typename TraitsType> 7406 template <typename TraitsType>
7410 void TargetDataX86<TraitsType>::lowerGlobals( 7407 void TargetDataX86<TraitsType>::lowerGlobals(
7411 const VariableDeclarationList &Vars, const std::string &SectionSuffix) { 7408 const VariableDeclarationList &Vars, const std::string &SectionSuffix) {
7412 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); 7409 const bool IsPIC = getFlags().getUseNonsfi();
7413 switch (Ctx->getFlags().getOutFileType()) { 7410 switch (getFlags().getOutFileType()) {
7414 case FT_Elf: { 7411 case FT_Elf: {
7415 ELFObjectWriter *Writer = Ctx->getObjectWriter(); 7412 ELFObjectWriter *Writer = Ctx->getObjectWriter();
7416 Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC); 7413 Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC);
7417 } break; 7414 } break;
7418 case FT_Asm: 7415 case FT_Asm:
7419 case FT_Iasm: { 7416 case FT_Iasm: {
7420 const std::string TranslateOnly = Ctx->getFlags().getTranslateOnly(); 7417 const std::string TranslateOnly = getFlags().getTranslateOnly();
7421 OstreamLocker L(Ctx); 7418 OstreamLocker L(Ctx);
7422 for (const VariableDeclaration *Var : Vars) { 7419 for (const VariableDeclaration *Var : Vars) {
7423 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { 7420 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
7424 emitGlobal(*Var, SectionSuffix); 7421 emitGlobal(*Var, SectionSuffix);
7425 } 7422 }
7426 } 7423 }
7427 } break; 7424 } break;
7428 } 7425 }
7429 } 7426 }
7430 } // end of namespace X86NAMESPACE 7427 } // end of namespace X86NAMESPACE
7431 } // end of namespace Ice 7428 } // end of namespace Ice
7432 7429
7433 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 7430 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8664Traits.h ('k') | src/IceTranslator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698