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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1017453007: Subzero: Support non sequentially consistent memory orderings for atomic ops. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: More code review cleanup Created 5 years, 9 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/IceIntrinsics.cpp ('k') | tests_lit/llvm2ice_tests/abi-atomics.ll » ('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/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 2838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 OperandX8632Mem *Loc = 2849 OperandX8632Mem *Loc =
2850 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 2850 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
2851 _store(legalizeToVar(ElementToInsertNotLegalized), Loc); 2851 _store(legalizeToVar(ElementToInsertNotLegalized), Loc);
2852 2852
2853 Variable *T = makeReg(Ty); 2853 Variable *T = makeReg(Ty);
2854 _movp(T, Slot); 2854 _movp(T, Slot);
2855 _movp(Inst->getDest(), T); 2855 _movp(Inst->getDest(), T);
2856 } 2856 }
2857 } 2857 }
2858 2858
2859 namespace {
2860
2861 // Converts a ConstantInteger32 operand into its constant value, or
2862 // MemoryOrderInvalid if the operand is not a ConstantInteger32.
2863 uint64_t getConstantMemoryOrder(Operand *Opnd) {
2864 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
2865 return Integer->getValue();
2866 return Intrinsics::MemoryOrderInvalid;
2867 }
2868
2869 } // end of anonymous namespace
2870
2859 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { 2871 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
2860 switch (Instr->getIntrinsicInfo().ID) { 2872 switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
2861 case Intrinsics::AtomicCmpxchg: { 2873 case Intrinsics::AtomicCmpxchg: {
2862 if (!Intrinsics::VerifyMemoryOrder( 2874 if (!Intrinsics::isMemoryOrderValid(
2863 llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) { 2875 ID, getConstantMemoryOrder(Instr->getArg(3)),
2864 Func->setError("Unexpected memory ordering (success) for AtomicCmpxchg"); 2876 getConstantMemoryOrder(Instr->getArg(4)))) {
2865 return; 2877 Func->setError("Unexpected memory ordering for AtomicCmpxchg");
2866 }
2867 if (!Intrinsics::VerifyMemoryOrder(
2868 llvm::cast<ConstantInteger32>(Instr->getArg(4))->getValue())) {
2869 Func->setError("Unexpected memory ordering (failure) for AtomicCmpxchg");
2870 return; 2878 return;
2871 } 2879 }
2872 Variable *DestPrev = Instr->getDest(); 2880 Variable *DestPrev = Instr->getDest();
2873 Operand *PtrToMem = Instr->getArg(0); 2881 Operand *PtrToMem = Instr->getArg(0);
2874 Operand *Expected = Instr->getArg(1); 2882 Operand *Expected = Instr->getArg(1);
2875 Operand *Desired = Instr->getArg(2); 2883 Operand *Desired = Instr->getArg(2);
2876 if (tryOptimizedCmpxchgCmpBr(DestPrev, PtrToMem, Expected, Desired)) 2884 if (tryOptimizedCmpxchgCmpBr(DestPrev, PtrToMem, Expected, Desired))
2877 return; 2885 return;
2878 lowerAtomicCmpxchg(DestPrev, PtrToMem, Expected, Desired); 2886 lowerAtomicCmpxchg(DestPrev, PtrToMem, Expected, Desired);
2879 return; 2887 return;
2880 } 2888 }
2881 case Intrinsics::AtomicFence: 2889 case Intrinsics::AtomicFence:
2882 if (!Intrinsics::VerifyMemoryOrder( 2890 if (!Intrinsics::isMemoryOrderValid(
2883 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue())) { 2891 ID, getConstantMemoryOrder(Instr->getArg(0)))) {
2884 Func->setError("Unexpected memory ordering for AtomicFence"); 2892 Func->setError("Unexpected memory ordering for AtomicFence");
2885 return; 2893 return;
2886 } 2894 }
2887 _mfence(); 2895 _mfence();
2888 return; 2896 return;
2889 case Intrinsics::AtomicFenceAll: 2897 case Intrinsics::AtomicFenceAll:
2890 // NOTE: FenceAll should prevent and load/store from being moved 2898 // NOTE: FenceAll should prevent and load/store from being moved
2891 // across the fence (both atomic and non-atomic). The InstX8632Mfence 2899 // across the fence (both atomic and non-atomic). The InstX8632Mfence
2892 // instruction is currently marked coarsely as "HasSideEffects". 2900 // instruction is currently marked coarsely as "HasSideEffects".
2893 _mfence(); 2901 _mfence();
(...skipping 24 matching lines...) Expand all
2918 _mov(Dest, Result); 2926 _mov(Dest, Result);
2919 return; 2927 return;
2920 } 2928 }
2921 // The PNaCl ABI requires the byte size to be a compile-time constant. 2929 // The PNaCl ABI requires the byte size to be a compile-time constant.
2922 Func->setError("AtomicIsLockFree byte size should be compile-time const"); 2930 Func->setError("AtomicIsLockFree byte size should be compile-time const");
2923 return; 2931 return;
2924 } 2932 }
2925 case Intrinsics::AtomicLoad: { 2933 case Intrinsics::AtomicLoad: {
2926 // We require the memory address to be naturally aligned. 2934 // We require the memory address to be naturally aligned.
2927 // Given that is the case, then normal loads are atomic. 2935 // Given that is the case, then normal loads are atomic.
2928 if (!Intrinsics::VerifyMemoryOrder( 2936 if (!Intrinsics::isMemoryOrderValid(
2929 llvm::cast<ConstantInteger32>(Instr->getArg(1))->getValue())) { 2937 ID, getConstantMemoryOrder(Instr->getArg(1)))) {
2930 Func->setError("Unexpected memory ordering for AtomicLoad"); 2938 Func->setError("Unexpected memory ordering for AtomicLoad");
2931 return; 2939 return;
2932 } 2940 }
2933 Variable *Dest = Instr->getDest(); 2941 Variable *Dest = Instr->getDest();
2934 if (Dest->getType() == IceType_i64) { 2942 if (Dest->getType() == IceType_i64) {
2935 // Follow what GCC does and use a movq instead of what lowerLoad() 2943 // Follow what GCC does and use a movq instead of what lowerLoad()
2936 // normally does (split the load into two). 2944 // normally does (split the load into two).
2937 // Thus, this skips load/arithmetic op folding. Load/arithmetic folding 2945 // Thus, this skips load/arithmetic op folding. Load/arithmetic folding
2938 // can't happen anyway, since this is x86-32 and integer arithmetic only 2946 // can't happen anyway, since this is x86-32 and integer arithmetic only
2939 // happens on 32-bit quantities. 2947 // happens on 32-bit quantities.
(...skipping 11 matching lines...) Expand all
2951 InstLoad *Load = InstLoad::create(Func, Dest, Instr->getArg(0)); 2959 InstLoad *Load = InstLoad::create(Func, Dest, Instr->getArg(0));
2952 lowerLoad(Load); 2960 lowerLoad(Load);
2953 // Make sure the atomic load isn't elided when unused, by adding a FakeUse. 2961 // Make sure the atomic load isn't elided when unused, by adding a FakeUse.
2954 // Since lowerLoad may fuse the load w/ an arithmetic instruction, 2962 // Since lowerLoad may fuse the load w/ an arithmetic instruction,
2955 // insert the FakeUse on the last-inserted instruction's dest. 2963 // insert the FakeUse on the last-inserted instruction's dest.
2956 Context.insert( 2964 Context.insert(
2957 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); 2965 InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
2958 return; 2966 return;
2959 } 2967 }
2960 case Intrinsics::AtomicRMW: 2968 case Intrinsics::AtomicRMW:
2961 if (!Intrinsics::VerifyMemoryOrder( 2969 if (!Intrinsics::isMemoryOrderValid(
2962 llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) { 2970 ID, getConstantMemoryOrder(Instr->getArg(3)))) {
2963 Func->setError("Unexpected memory ordering for AtomicRMW"); 2971 Func->setError("Unexpected memory ordering for AtomicRMW");
2964 return; 2972 return;
2965 } 2973 }
2966 lowerAtomicRMW(Instr->getDest(), 2974 lowerAtomicRMW(Instr->getDest(),
2967 static_cast<uint32_t>(llvm::cast<ConstantInteger32>( 2975 static_cast<uint32_t>(llvm::cast<ConstantInteger32>(
2968 Instr->getArg(0))->getValue()), 2976 Instr->getArg(0))->getValue()),
2969 Instr->getArg(1), Instr->getArg(2)); 2977 Instr->getArg(1), Instr->getArg(2));
2970 return; 2978 return;
2971 case Intrinsics::AtomicStore: { 2979 case Intrinsics::AtomicStore: {
2972 if (!Intrinsics::VerifyMemoryOrder( 2980 if (!Intrinsics::isMemoryOrderValid(
2973 llvm::cast<ConstantInteger32>(Instr->getArg(2))->getValue())) { 2981 ID, getConstantMemoryOrder(Instr->getArg(2)))) {
2974 Func->setError("Unexpected memory ordering for AtomicStore"); 2982 Func->setError("Unexpected memory ordering for AtomicStore");
2975 return; 2983 return;
2976 } 2984 }
2977 // We require the memory address to be naturally aligned. 2985 // We require the memory address to be naturally aligned.
2978 // Given that is the case, then normal stores are atomic. 2986 // Given that is the case, then normal stores are atomic.
2979 // Add a fence after the store to make it visible. 2987 // Add a fence after the store to make it visible.
2980 Operand *Value = Instr->getArg(0); 2988 Operand *Value = Instr->getArg(0);
2981 Operand *Ptr = Instr->getArg(1); 2989 Operand *Ptr = Instr->getArg(1);
2982 if (Value->getType() == IceType_i64) { 2990 if (Value->getType() == IceType_i64) {
2983 // Use a movq instead of what lowerStore() normally does 2991 // Use a movq instead of what lowerStore() normally does
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
4478 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { 4486 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) {
4479 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); 4487 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand);
4480 // It may be the case that address mode optimization already creates 4488 // It may be the case that address mode optimization already creates
4481 // an OperandX8632Mem, so in that case it wouldn't need another level 4489 // an OperandX8632Mem, so in that case it wouldn't need another level
4482 // of transformation. 4490 // of transformation.
4483 if (!Mem) { 4491 if (!Mem) {
4484 Variable *Base = llvm::dyn_cast<Variable>(Operand); 4492 Variable *Base = llvm::dyn_cast<Variable>(Operand);
4485 Constant *Offset = llvm::dyn_cast<Constant>(Operand); 4493 Constant *Offset = llvm::dyn_cast<Constant>(Operand);
4486 assert(Base || Offset); 4494 assert(Base || Offset);
4487 if (Offset) { 4495 if (Offset) {
4496 // Make sure Offset is not undef.
4497 Offset = llvm::cast<Constant>(legalize(Offset));
4488 assert(llvm::isa<ConstantInteger32>(Offset) || 4498 assert(llvm::isa<ConstantInteger32>(Offset) ||
4489 llvm::isa<ConstantRelocatable>(Offset)); 4499 llvm::isa<ConstantRelocatable>(Offset));
4490 } 4500 }
4491 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); 4501 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
4492 } 4502 }
4493 return llvm::cast<OperandX8632Mem>(legalize(Mem)); 4503 return llvm::cast<OperandX8632Mem>(legalize(Mem));
4494 } 4504 }
4495 4505
4496 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 4506 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
4497 // There aren't any 64-bit integer registers for x86-32. 4507 // There aren't any 64-bit integer registers for x86-32.
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4788 case FT_Asm: 4798 case FT_Asm:
4789 case FT_Iasm: { 4799 case FT_Iasm: {
4790 OstreamLocker L(Ctx); 4800 OstreamLocker L(Ctx);
4791 emitConstantPool<PoolTypeConverter<float>>(Ctx); 4801 emitConstantPool<PoolTypeConverter<float>>(Ctx);
4792 emitConstantPool<PoolTypeConverter<double>>(Ctx); 4802 emitConstantPool<PoolTypeConverter<double>>(Ctx);
4793 } break; 4803 } break;
4794 } 4804 }
4795 } 4805 }
4796 4806
4797 } // end of namespace Ice 4807 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceIntrinsics.cpp ('k') | tests_lit/llvm2ice_tests/abi-atomics.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698