@@ -485,28 +485,23 @@ void OCLToSPIRVBase::visitCallAsyncWorkGroupCopy(CallInst *CI,
485
485
}
486
486
487
487
CallInst *OCLToSPIRVBase::visitCallAtomicCmpXchg (CallInst *CI) {
488
- AttributeList Attrs = CI->getCalledFunction ()->getAttributes ();
489
- Value *Expected = nullptr ;
490
488
CallInst *NewCI = nullptr ;
491
- mutateCallInstOCL (
492
- M, CI,
493
- [&](CallInst *CI, std::vector<Value *> &Args, Type *&RetTy) {
494
- Expected = Args[1 ]; // temporary save second argument.
495
- RetTy = Args[2 ]->getType ();
496
- Args[1 ] = new LoadInst (RetTy, Args[1 ], " exp" , false , CI);
497
- assert (Args[1 ]->getType ()->isIntegerTy () &&
498
- Args[2 ]->getType ()->isIntegerTy () &&
499
- " In SPIR-V 1.0 arguments of OpAtomicCompareExchange must be "
500
- " an integer type scalars" );
501
- return kOCLBuiltinName ::AtomicCmpXchgStrong;
502
- },
503
- [&](CallInst *NCI) -> Instruction * {
504
- NewCI = NCI;
505
- Instruction *Store = new StoreInst (NCI, Expected, NCI->getNextNode ());
506
- return new ICmpInst (Store->getNextNode (), CmpInst::ICMP_EQ, NCI,
507
- NCI->getArgOperand (1 ));
508
- },
509
- &Attrs);
489
+ {
490
+ auto Mutator = mutateCallInst (CI, kOCLBuiltinName ::AtomicCmpXchgStrong);
491
+ Value *Expected = Mutator.getArg (1 );
492
+ Type *MemTy = Mutator.getArg (2 )->getType ();
493
+ assert (MemTy->isIntegerTy () &&
494
+ " In SPIR-V 1.0 arguments of OpAtomicCompareExchange must be "
495
+ " an integer type scalars" );
496
+ Mutator.mapArg (1 , [=](IRBuilder<> &Builder, Value *V) {
497
+ return Builder.CreateLoad (MemTy, V, " exp" );
498
+ });
499
+ Mutator.changeReturnType (MemTy, [&](IRBuilder<> &Builder, CallInst *NCI) {
500
+ NewCI = NCI;
501
+ Builder.CreateStore (NCI, Expected);
502
+ return Builder.CreateICmpEQ (NCI, NCI->getArgOperand (1 ));
503
+ });
504
+ }
510
505
return NewCI;
511
506
}
512
507
@@ -570,17 +565,10 @@ void OCLToSPIRVBase::visitCallMemFence(CallInst *CI, StringRef DemangledName) {
570
565
void OCLToSPIRVBase::transMemoryBarrier (CallInst *CI,
571
566
AtomicWorkItemFenceLiterals Lit) {
572
567
assert (CI->getCalledFunction () && " Unexpected indirect call" );
573
- AttributeList Attrs = CI->getCalledFunction ()->getAttributes ();
574
- mutateCallInstSPIRV (
575
- M, CI,
576
- [=](CallInst *, std::vector<Value *> &Args) {
577
- Args.resize (2 );
578
- Args[0 ] = addInt32 (map<Scope>(std::get<2 >(Lit)));
579
- Args[1 ] = addInt32 (
580
- mapOCLMemSemanticToSPIRV (std::get<0 >(Lit), std::get<1 >(Lit)));
581
- return getSPIRVFuncName (OpMemoryBarrier);
582
- },
583
- &Attrs);
568
+ mutateCallInst (CI, OpMemoryBarrier)
569
+ .setArgs ({addInt32 (map<Scope>(std::get<2 >(Lit))),
570
+ addInt32 (mapOCLMemSemanticToSPIRV (std::get<0 >(Lit),
571
+ std::get<1 >(Lit)))});
584
572
}
585
573
586
574
void OCLToSPIRVBase::visitCallAtomicLegacy (CallInst *CI, StringRef MangledName,
@@ -747,25 +735,18 @@ void OCLToSPIRVBase::transAtomicBuiltin(CallInst *CI,
747
735
748
736
void OCLToSPIRVBase::visitCallBarrier (CallInst *CI) {
749
737
auto Lit = getBarrierLiterals (CI);
750
- AttributeList Attrs = CI->getCalledFunction ()->getAttributes ();
751
- mutateCallInstSPIRV (
752
- M, CI,
753
- [=](CallInst *, std::vector<Value *> &Args) {
754
- Args.resize (3 );
755
- // Execution scope
756
- Args[0 ] = addInt32 (map<Scope>(std::get<2 >(Lit)));
757
- // Memory scope
758
- Args[1 ] = addInt32 (map<Scope>(std::get<1 >(Lit)));
759
- // Use sequential consistent memory order by default.
760
- // But if the flags argument is set to 0, we use
761
- // None(Relaxed) memory order.
762
- unsigned MemFenceFlag = std::get<0 >(Lit);
763
- OCLMemOrderKind MemOrder = MemFenceFlag ? OCLMO_seq_cst : OCLMO_relaxed;
764
- Args[2 ] = addInt32 (mapOCLMemSemanticToSPIRV (
765
- MemFenceFlag, MemOrder)); // Memory semantics
766
- return getSPIRVFuncName (OpControlBarrier);
767
- },
768
- &Attrs);
738
+ // Use sequential consistent memory order by default.
739
+ // But if the flags argument is set to 0, we use
740
+ // None(Relaxed) memory order.
741
+ unsigned MemFenceFlag = std::get<0 >(Lit);
742
+ OCLMemOrderKind MemOrder = MemFenceFlag ? OCLMO_seq_cst : OCLMO_relaxed;
743
+ mutateCallInst (CI, OpControlBarrier)
744
+ .setArgs ({// Execution scope
745
+ addInt32 (map<Scope>(std::get<2 >(Lit))),
746
+ // Memory scope
747
+ addInt32 (map<Scope>(std::get<1 >(Lit))),
748
+ // Memory semantics
749
+ addInt32 (mapOCLMemSemanticToSPIRV (MemFenceFlag, MemOrder))});
769
750
}
770
751
771
752
void OCLToSPIRVBase::visitCallConvert (CallInst *CI, StringRef MangledName,
@@ -1300,19 +1281,12 @@ void OCLToSPIRVBase::visitCallVecLoadStore(CallInst *CI, StringRef MangledName,
1300
1281
}
1301
1282
1302
1283
void OCLToSPIRVBase::visitCallGetFence (CallInst *CI, StringRef DemangledName) {
1303
- AttributeList Attrs = CI->getCalledFunction ()->getAttributes ();
1304
1284
Op OC = OpNop;
1305
1285
OCLSPIRVBuiltinMap::find (DemangledName.str (), &OC);
1306
- std::string SPIRVName = getSPIRVFuncName (OC);
1307
- mutateCallInstSPIRV (
1308
- M, CI,
1309
- [=](CallInst *, std::vector<Value *> &Args, Type *&Ret) {
1310
- return SPIRVName;
1311
- },
1312
- [=](CallInst *NewCI) -> Instruction * {
1313
- return BinaryOperator::CreateLShr (NewCI, getInt32 (M, 8 ), " " , CI);
1314
- },
1315
- &Attrs);
1286
+ mutateCallInst (CI, OC).changeReturnType (
1287
+ CI->getType (), [](IRBuilder<> &Builder, CallInst *NewCI) {
1288
+ return Builder.CreateLShr (NewCI, Builder.getInt32 (8 ));
1289
+ });
1316
1290
}
1317
1291
1318
1292
void OCLToSPIRVBase::visitCallDot (CallInst *CI) {
@@ -1877,32 +1851,26 @@ void OCLToSPIRVBase::visitSubgroupAVCBuiltinCallWithSampler(
1877
1851
void OCLToSPIRVBase::visitCallSplitBarrierINTEL (CallInst *CI,
1878
1852
StringRef DemangledName) {
1879
1853
auto Lit = getBarrierLiterals (CI);
1880
- AttributeList Attrs = CI->getCalledFunction ()->getAttributes ();
1881
1854
Op OpCode =
1882
1855
StringSwitch<Op>(DemangledName)
1883
1856
.Case (" intel_work_group_barrier_arrive" , OpControlBarrierArriveINTEL)
1884
1857
.Case (" intel_work_group_barrier_wait" , OpControlBarrierWaitINTEL)
1885
1858
.Default (OpNop);
1886
1859
1887
- mutateCallInstSPIRV (
1888
- M, CI,
1889
- [=](CallInst *, std::vector<Value *> &Args) {
1890
- Args.resize (3 );
1891
- // Execution scope
1892
- Args[0 ] = addInt32 (map<Scope>(std::get<2 >(Lit)));
1893
- // Memory scope
1894
- Args[1 ] = addInt32 (map<Scope>(std::get<1 >(Lit)));
1895
- // Memory semantics
1896
- // OpControlBarrierArriveINTEL -> Release,
1897
- // OpControlBarrierWaitINTEL -> Acquire
1898
- unsigned MemFenceFlag = std::get<0 >(Lit);
1899
- OCLMemOrderKind MemOrder = OpCode == OpControlBarrierArriveINTEL
1900
- ? OCLMO_release
1901
- : OCLMO_acquire;
1902
- Args[2 ] = addInt32 (mapOCLMemSemanticToSPIRV (MemFenceFlag, MemOrder));
1903
- return getSPIRVFuncName (OpCode);
1904
- },
1905
- &Attrs);
1860
+ // Map memory semantics as follows:
1861
+ // OpControlBarrierArriveINTEL -> Release,
1862
+ // OpControlBarrierWaitINTEL -> Acquire
1863
+ unsigned MemFenceFlag = std::get<0 >(Lit);
1864
+ OCLMemOrderKind MemOrder =
1865
+ OpCode == OpControlBarrierArriveINTEL ? OCLMO_release : OCLMO_acquire;
1866
+ mutateCallInst (CI, OpCode)
1867
+ .removeArgs (0 , CI->arg_size ())
1868
+ // Execution scope
1869
+ .appendArg (addInt32 (map<Scope>(std::get<2 >(Lit))))
1870
+ // Memory scope
1871
+ .appendArg (addInt32 (map<Scope>(std::get<1 >(Lit))))
1872
+ // Memory semantics
1873
+ .appendArg (addInt32 (mapOCLMemSemanticToSPIRV (MemFenceFlag, MemOrder)));
1906
1874
}
1907
1875
1908
1876
void OCLToSPIRVBase::visitCallLdexp (CallInst *CI, StringRef MangledName,
0 commit comments