@@ -82,7 +82,9 @@ IN THE SOFTWARE.
82
82
#include " common/debug/Dump.hpp"
83
83
#include " Compiler/IGCPassSupport.h"
84
84
#include " common/LLVMWarningsPush.hpp"
85
+ #include " llvmWrapper/IR/Instructions.h"
85
86
#include < llvm/IR/InstIterator.h>
87
+ #include < llvm/IR/InlineAsm.h>
86
88
#include " common/LLVMWarningsPop.hpp"
87
89
#include < algorithm>
88
90
#include " Probe/Assertion.h"
@@ -1017,6 +1019,37 @@ DeSSA::getInsEltRoot(Value* Val) const
1017
1019
return RI->second ;
1018
1020
}
1019
1021
1022
+ // / <summary>
1023
+ // / Identify if an instruction has partial write semantics
1024
+ // / </summary>
1025
+ // / <param name="Inst"></param>
1026
+ // / <returns> the index of the source partial-write operand</returns>
1027
+ static
1028
+ int getPartialWriteSource (Value *Inst)
1029
+ {
1030
+ if (isa<InsertElementInst>(Inst))
1031
+ return 0 ; // source 0 is the original value
1032
+ if (auto CI = dyn_cast<CallInst>(Inst)) {
1033
+ // only handle inline-asm with simple destination
1034
+ if (CI->isInlineAsm () && !CI->getType ()->isStructTy ()) {
1035
+ InlineAsm* IA = cast<InlineAsm>(IGCLLVM::getCalledValue (CI));
1036
+ StringRef constraintStr (IA->getConstraintString ());
1037
+ SmallVector<StringRef, 8 > constraints;
1038
+ constraintStr.split (constraints, ' ,' );
1039
+ for (int i = 0 ; i < (int )constraints.size (); i++) {
1040
+ unsigned destID;
1041
+ if (constraints[i].getAsInteger (10 , destID) == 0 ) {
1042
+ // constraint-string indicates that source(i-1) and
1043
+ // destination should be the same vISA variable
1044
+ if (i > 0 && destID == 0 )
1045
+ return (i - 1 );
1046
+ }
1047
+ }
1048
+ }
1049
+ }
1050
+ return -1 ;
1051
+ }
1052
+
1020
1053
void
1021
1054
DeSSA::CoalesceInsertElementsForBasicBlock (BasicBlock* Blk)
1022
1055
{
@@ -1035,9 +1068,10 @@ DeSSA::CoalesceInsertElementsForBasicBlock(BasicBlock* Blk)
1035
1068
}
1036
1069
1037
1070
// For keeping the existing behavior of InsEltMap unchanged
1038
- if (isa<InsertElementInst>(Inst))
1071
+ auto PWSrcIdx = getPartialWriteSource (Inst);
1072
+ if (PWSrcIdx >= 0 )
1039
1073
{
1040
- Value* origSrcV = Inst->getOperand (0 );
1074
+ Value* origSrcV = Inst->getOperand (PWSrcIdx );
1041
1075
Value* SrcV = getAliasee (origSrcV);
1042
1076
if (SrcV != Inst && isArgOrNeededInst (origSrcV))
1043
1077
{
@@ -1076,21 +1110,22 @@ DeSSA::CoalesceInsertElementsForBasicBlock(BasicBlock* Blk)
1076
1110
// extend the liveness of InsertElement due to union
1077
1111
for (unsigned i = 0 ; i < Inst->getNumOperands (); ++i) {
1078
1112
Value* SrcV = Inst->getOperand (i);
1079
- if (isa<InsertElementInst> (SrcV)) {
1113
+ if (getPartialWriteSource (SrcV) >= 0 ) {
1080
1114
Value* RootV = getInsEltRoot (SrcV);
1081
1115
if (RootV != SrcV) {
1082
1116
LV->HandleVirtRegUse (RootV, Blk, Inst, true );
1083
1117
}
1084
1118
}
1085
1119
}
1086
1120
1087
- if (!isa<InsertElementInst>(Inst)) {
1121
+ auto PWSrcIdx = getPartialWriteSource (Inst);
1122
+ if (PWSrcIdx < 0 ) {
1088
1123
continue ;
1089
1124
}
1090
1125
// handle InsertElement
1091
1126
InsEltMapAddValue (Inst);
1092
1127
1093
- Value* SrcV = Inst->getOperand (0 );
1128
+ Value* SrcV = Inst->getOperand (PWSrcIdx );
1094
1129
if (isa<Instruction>(SrcV) || isa<Argument>(SrcV)) {
1095
1130
if (!LV->isLiveAt (SrcV, Inst)) {
1096
1131
Instruction* SrcDef = dyn_cast<Instruction>(SrcV);
0 commit comments