|
1 | 1 | /*========================== begin_copyright_notice ============================ |
2 | 2 |
|
3 | | -Copyright (C) 2017-2023 Intel Corporation |
| 3 | +Copyright (C) 2017-2025 Intel Corporation |
4 | 4 |
|
5 | 5 | SPDX-License-Identifier: MIT |
6 | 6 |
|
@@ -2172,7 +2172,8 @@ bool GenXSimdCFConformance::checkEMVal(SimpleValue EMVal) { |
2172 | 2172 | return false; // uses constant that is not all ones, invalid |
2173 | 2173 | } |
2174 | 2174 | } else if (!EMVals.count(ConnectedVal)) { |
2175 | | - LLVM_DEBUG(dbgs() << "checkEMVal: ConnectedVal is not in EMVals\n"); |
| 2175 | + LLVM_DEBUG(dbgs() << "checkEMVal: ConnectedVal is not in EMVals : "); |
| 2176 | + LLVM_DEBUG(dbgs() << "val == " << *ConnectedVal.getValue() << "\n"); |
2176 | 2177 | return false; // connected value is not in EMVals |
2177 | 2178 | } |
2178 | 2179 | LLVM_DEBUG(dbgs() << "checkEMVal: ConnectedVal checked " |
@@ -2558,6 +2559,34 @@ static bool checkAllUsesAreSelectOrWrRegion(Value *V) { |
2558 | 2559 | return true; |
2559 | 2560 | } |
2560 | 2561 |
|
| 2562 | +static inline void PrepareFunctionAttributes(Function *CalledFunc, |
| 2563 | + Type *ValTy) { |
| 2564 | + if (CalledFunc->hasFnAttribute(vc::FunctionMD::VCSimdCFArg)) { |
| 2565 | + for (auto *Arg = CalledFunc->arg_begin(); Arg != CalledFunc->arg_end(); |
| 2566 | + ++Arg) |
| 2567 | + if (Arg->getType() == ValTy) { |
| 2568 | + CalledFunc->removeFnAttr(vc::FunctionMD::VCSimdCFArg); |
| 2569 | + LLVM_DEBUG(dbgs() << "Remove VCSimdCFArg attr from " |
| 2570 | + << CalledFunc->getName() << "\n"); |
| 2571 | + break; |
| 2572 | + } |
| 2573 | + } |
| 2574 | + if (CalledFunc->hasFnAttribute(vc::FunctionMD::VCSimdCFRet)) { |
| 2575 | + auto *RetTy = CalledFunc->getReturnType(); |
| 2576 | + if (auto *ST = dyn_cast<StructType>(RetTy)) { |
| 2577 | + unsigned RetIdx = 0; |
| 2578 | + for (unsigned End = IndexFlattener::getNumElements(ST); RetIdx < End; |
| 2579 | + ++RetIdx) { |
| 2580 | + auto *Ty = IndexFlattener::getElementType(ST, RetIdx); |
| 2581 | + if (Ty->isVectorTy() && Ty->getScalarType()->isIntegerTy(1)) |
| 2582 | + CalledFunc->removeFnAttr(vc::FunctionMD::VCSimdCFRet); |
| 2583 | + } |
| 2584 | + } |
| 2585 | + if (RetTy->isVectorTy() && RetTy->getScalarType()->isIntegerTy(1)) |
| 2586 | + CalledFunc->removeFnAttr(vc::FunctionMD::VCSimdCFRet); |
| 2587 | + } |
| 2588 | +} |
| 2589 | + |
2561 | 2590 | /*********************************************************************** |
2562 | 2591 | * getConnectedVals : for a SimpleValue, get other SimpleValues connected to |
2563 | 2592 | * it through phi nodes, insertvalue, extractvalue, goto/join, and maybe |
@@ -2622,7 +2651,8 @@ bool GenXSimdCFConformance::getConnectedVals( |
2622 | 2651 | break; |
2623 | 2652 | } |
2624 | 2653 | } else if (RetTy != ValTy && !RetTy->isVoidTy()) |
2625 | | - return false; // no predicate ret value found |
| 2654 | + return F->hasFnAttribute( |
| 2655 | + vc::FunctionMD::VCSimdCFRet); // no predicate ret value found |
2626 | 2656 | if (!RetTy->isVoidTy()) |
2627 | 2657 | for (auto fi = F->begin(), fe = F->end(); fi != fe; ++fi) |
2628 | 2658 | if (auto *Ret = dyn_cast<ReturnInst>(fi->getTerminator())) |
@@ -2732,14 +2762,18 @@ bool GenXSimdCFConformance::getConnectedVals( |
2732 | 2762 | // about that. |
2733 | 2763 | auto ValTy = |
2734 | 2764 | IndexFlattener::getElementType(Val.getType(), Val.getIndex()); |
2735 | | - for (unsigned Idx = 0, End = IGCLLVM::getNumArgOperands(CI);; ++Idx) { |
2736 | | - if (Idx == End) |
2737 | | - return false; // no corresponding call arg found |
2738 | | - if (CI->getArgOperand(Idx)->getType() == ValTy) { |
2739 | | - ConnectedVals->push_back(SimpleValue(CI->getArgOperand(Idx), 0)); |
2740 | | - break; |
| 2765 | + |
| 2766 | + PrepareFunctionAttributes(CalledFunc, ValTy); |
| 2767 | + |
| 2768 | + if (!CalledFunc->hasFnAttribute(vc::FunctionMD::VCSimdCFArg)) |
| 2769 | + for (unsigned Idx = 0, End = IGCLLVM::getNumArgOperands(CI);; ++Idx) { |
| 2770 | + if (Idx == End) |
| 2771 | + return false; // no corresponding call arg found |
| 2772 | + if (CI->getArgOperand(Idx)->getType() == ValTy) { |
| 2773 | + ConnectedVals->push_back(SimpleValue(CI->getArgOperand(Idx), 0)); |
| 2774 | + break; |
| 2775 | + } |
2741 | 2776 | } |
2742 | | - } |
2743 | 2777 | break; |
2744 | 2778 | } |
2745 | 2779 | default: |
@@ -2809,22 +2843,25 @@ bool GenXSimdCFConformance::getConnectedVals( |
2809 | 2843 | auto ValTy = |
2810 | 2844 | IndexFlattener::getElementType(Val.getType(), Val.getIndex()); |
2811 | 2845 | auto F = User->getFunction(); |
| 2846 | + |
2812 | 2847 | bool Lower = false; |
2813 | | - for (auto ai = F->arg_begin(), ae = F->arg_end();; ++ai) { |
2814 | | - if (ai == ae) { |
2815 | | - // no arg of the right type found |
2816 | | - Lower = true; |
2817 | | - UsersToLower.push_back(SimpleValue(User, ui->getOperandNo())); |
2818 | | - LLVM_DEBUG(dbgs() << "getConnectedVals: ai == ae push_back " << *User |
2819 | | - << " No=" << ui->getOperandNo() << "\n"); |
2820 | | - break; |
2821 | | - } |
2822 | | - auto Arg = &*ai; |
2823 | | - if (Arg->getType() == ValTy) { |
2824 | | - ConnectedVals->push_back(SimpleValue(Arg, 0)); |
2825 | | - break; |
| 2848 | + PrepareFunctionAttributes(F, ValTy); |
| 2849 | + if (!F->hasFnAttribute(vc::FunctionMD::VCSimdCFArg)) |
| 2850 | + for (auto ai = F->arg_begin(), ae = F->arg_end();; ++ai) { |
| 2851 | + if (ai == ae) { |
| 2852 | + // no arg of the right type found |
| 2853 | + Lower = true; |
| 2854 | + UsersToLower.push_back(SimpleValue(User, ui->getOperandNo())); |
| 2855 | + LLVM_DEBUG(dbgs() << "getConnectedVals: ai == ae push_back " |
| 2856 | + << *User << " No=" << ui->getOperandNo() << "\n"); |
| 2857 | + break; |
| 2858 | + } |
| 2859 | + auto Arg = &*ai; |
| 2860 | + if (Arg->getType() == ValTy) { |
| 2861 | + ConnectedVals->push_back(SimpleValue(Arg, 0)); |
| 2862 | + break; |
| 2863 | + } |
2826 | 2864 | } |
2827 | | - } |
2828 | 2865 | if (IncludeOptional && !Lower) { |
2829 | 2866 | // With IncludeOptional, also add the values connected by being the |
2830 | 2867 | // return value at each call site. |
@@ -2946,41 +2983,50 @@ bool GenXSimdCFConformance::getConnectedVals( |
2946 | 2983 | // Use in subroutine call. Add the corresponding function arg. |
2947 | 2984 | Function *CalledFunc = CI->getCalledFunction(); |
2948 | 2985 | IGC_ASSERT(CalledFunc); |
2949 | | - auto ai = CalledFunc->arg_begin(); |
2950 | | - for (unsigned Count = ui->getOperandNo(); Count; --Count, ++ai) |
2951 | | - ; |
2952 | | - Argument *Arg = &*ai; |
2953 | | - ConnectedVals->push_back(SimpleValue(Arg, Val.getIndex())); |
| 2986 | + |
| 2987 | + auto ValTy = IndexFlattener::getElementType(Val.getValue()->getType(), |
| 2988 | + Val.getIndex()); |
| 2989 | + |
| 2990 | + PrepareFunctionAttributes(CalledFunc, ValTy); |
| 2991 | + // If Attribute setted - do not check |
| 2992 | + if (!CalledFunc->hasFnAttribute(vc::FunctionMD::VCSimdCFArg)) { |
| 2993 | + |
| 2994 | + auto ai = CalledFunc->arg_begin(); |
| 2995 | + for (unsigned Count = ui->getOperandNo(); Count; --Count, ++ai) |
| 2996 | + ; |
| 2997 | + Argument *Arg = &*ai; |
| 2998 | + ConnectedVals->push_back(SimpleValue(Arg, Val.getIndex())); |
| 2999 | + } |
2954 | 3000 | // Connected to some return value from the call. There is a problem |
2955 | 3001 | // here in that it might find another predicate return value that is |
2956 | 3002 | // nothing to do with SIMD CF, and thus stop SIMD CF being optimized. |
2957 | 3003 | // But passing a predicate in and out of a function is rare outside |
2958 | 3004 | // of SIMD CF, so we do not worry about that. |
2959 | | - unsigned RetIdx = 0; |
2960 | | - auto ValTy = IndexFlattener::getElementType(Val.getValue()->getType(), |
2961 | | - Val.getIndex()); |
2962 | | - if (auto *ST = dyn_cast<StructType>(CI->getType())) { |
2963 | | - LLVM_DEBUG(dbgs() |
2964 | | - << "getConnectedVals: StructType get" << *ST << "\n"); |
2965 | | - for (unsigned End = IndexFlattener::getNumElements(ST);; ++RetIdx) { |
2966 | | - if (RetIdx == End) { |
2967 | | - UsersToLower.push_back(SimpleValue( |
2968 | | - User, ui->getOperandNo())); // no predicate ret value found |
2969 | | - LLVM_DEBUG(dbgs() << "getConnectedVals: push_back " << *CI |
2970 | | - << " No=" << ui->getOperandNo() << "\n"); |
2971 | | - } |
2972 | | - if (IndexFlattener::getElementType(ST, RetIdx) == ValTy) { |
2973 | | - ConnectedVals->push_back(SimpleValue(CI, RetIdx)); |
2974 | | - break; |
| 3005 | + if (!CalledFunc->hasFnAttribute(vc::FunctionMD::VCSimdCFRet)) { |
| 3006 | + unsigned RetIdx = 0; |
| 3007 | + if (auto *ST = dyn_cast<StructType>(CI->getType())) { |
| 3008 | + LLVM_DEBUG(dbgs() |
| 3009 | + << "getConnectedVals: StructType get" << *ST << "\n"); |
| 3010 | + for (unsigned End = IndexFlattener::getNumElements(ST);; ++RetIdx) { |
| 3011 | + if (RetIdx == End) { |
| 3012 | + UsersToLower.push_back(SimpleValue( |
| 3013 | + User, ui->getOperandNo())); // no predicate ret value found |
| 3014 | + LLVM_DEBUG(dbgs() << "getConnectedVals: push_back " << *CI |
| 3015 | + << " No=" << ui->getOperandNo() << "\n"); |
| 3016 | + } |
| 3017 | + if (IndexFlattener::getElementType(ST, RetIdx) == ValTy) { |
| 3018 | + ConnectedVals->push_back(SimpleValue(CI, RetIdx)); |
| 3019 | + break; |
| 3020 | + } |
2975 | 3021 | } |
| 3022 | + } else if (CI->getType() == ValTy) |
| 3023 | + ConnectedVals->push_back(SimpleValue(CI, 0)); |
| 3024 | + else if (!CI->getType()->isVoidTy()) { |
| 3025 | + UsersToLower.push_back(SimpleValue( |
| 3026 | + User, ui->getOperandNo())); // no predicate ret value found |
| 3027 | + LLVM_DEBUG(dbgs() << "getConnectedVals: push_back " << *CI |
| 3028 | + << " No=" << ui->getOperandNo() << "\n"); |
2976 | 3029 | } |
2977 | | - } else if (CI->getType() == ValTy) |
2978 | | - ConnectedVals->push_back(SimpleValue(CI, 0)); |
2979 | | - else if (!CI->getType()->isVoidTy()) { |
2980 | | - UsersToLower.push_back(SimpleValue( |
2981 | | - User, ui->getOperandNo())); // no predicate ret value found |
2982 | | - LLVM_DEBUG(dbgs() << "getConnectedVals: push_back " << *CI |
2983 | | - << " No=" << ui->getOperandNo() << "\n"); |
2984 | 3030 | } |
2985 | 3031 | break; |
2986 | 3032 | } |
|
0 commit comments