@@ -2891,10 +2891,11 @@ struct AnnotationDecorations {
2891
2891
DecorationsInfoVec MemoryAttributesVec;
2892
2892
DecorationsInfoVec MemoryAccessesVec;
2893
2893
DecorationsInfoVec BufferLocationVec;
2894
+ DecorationsInfoVec LatencyControlVec;
2894
2895
2895
2896
bool empty () {
2896
2897
return (MemoryAttributesVec.empty () && MemoryAccessesVec.empty () &&
2897
- BufferLocationVec.empty ());
2898
+ BufferLocationVec.empty () && LatencyControlVec. empty () );
2898
2899
}
2899
2900
};
2900
2901
@@ -3028,8 +3029,8 @@ static bool tryParseAnnotationDecoValues(StringRef ValueStr,
3028
3029
return false ;
3029
3030
// Skip the , delimiter and go directly to the start of next value.
3030
3031
ValueStart = (++I) + 1 ;
3032
+ continue ;
3031
3033
}
3032
- continue ;
3033
3034
}
3034
3035
if (CurrentC == ' ,' ) {
3035
3036
// Since we are not currently in a string literal, comma denotes a
@@ -3064,7 +3065,6 @@ static bool tryParseAnnotationDecoValues(StringRef ValueStr,
3064
3065
AnnotationDecorations tryParseAnnotationString (SPIRVModule *BM,
3065
3066
StringRef AnnotatedCode) {
3066
3067
AnnotationDecorations Decorates;
3067
-
3068
3068
// Annotation string decorations are separated into {word} OR
3069
3069
// {word:value,value,...} blocks, where value is either a word (including
3070
3070
// numbers) or a quotation mark enclosed string.
@@ -3088,6 +3088,8 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3088
3088
ExtensionID::SPV_INTEL_fpga_memory_attributes);
3089
3089
const bool AllowFPGABufLoc =
3090
3090
BM->isAllowedToUseExtension (ExtensionID::SPV_INTEL_fpga_buffer_location);
3091
+ const bool AllowFPGALatencyControl =
3092
+ BM->isAllowedToUseExtension (ExtensionID::SPV_INTEL_fpga_latency_control);
3091
3093
3092
3094
bool ValidDecorationFound = false ;
3093
3095
DecorationsInfoVec DecorationsVec;
@@ -3111,6 +3113,12 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3111
3113
DecorationKind == DecorationBufferLocationINTEL) {
3112
3114
Decorates.BufferLocationVec .emplace_back (
3113
3115
static_cast <Decoration>(DecorationKind), std::move (DecValues));
3116
+ } else if (AllowFPGALatencyControl &&
3117
+ (DecorationKind == DecorationLatencyControlLabelINTEL ||
3118
+ DecorationKind ==
3119
+ DecorationLatencyControlConstraintINTEL)) {
3120
+ Decorates.LatencyControlVec .emplace_back (
3121
+ static_cast <Decoration>(DecorationKind), std::move (DecValues));
3114
3122
} else {
3115
3123
DecorationsVec.emplace_back (static_cast <Decoration>(DecorationKind),
3116
3124
std::move (DecValues));
@@ -3203,12 +3211,12 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3203
3211
}
3204
3212
3205
3213
std::vector<SPIRVWord>
3206
- getBankBitsFromStrings (const std::vector<std::string> &BitsStrings ) {
3207
- std::vector<SPIRVWord> Bits (BitsStrings .size ());
3208
- for (size_t J = 0 ; J < BitsStrings .size (); ++J)
3209
- if (StringRef (BitsStrings [J]).getAsInteger (10 , Bits [J]))
3214
+ getLiteralsFromStrings (const std::vector<std::string> &Strings ) {
3215
+ std::vector<SPIRVWord> Literals (Strings .size ());
3216
+ for (size_t J = 0 ; J < Strings .size (); ++J)
3217
+ if (StringRef (Strings [J]).getAsInteger (10 , Literals [J]))
3210
3218
return {};
3211
- return Bits ;
3219
+ return Literals ;
3212
3220
}
3213
3221
3214
3222
void addAnnotationDecorations (SPIRVEntry *E, DecorationsInfoVec &Decorations) {
@@ -3254,7 +3262,7 @@ void addAnnotationDecorations(SPIRVEntry *E, DecorationsInfoVec &Decorations) {
3254
3262
I.second .size () > 0 , SPIRVEC_InvalidLlvmModule,
3255
3263
" BankBitsINTEL requires at least one argument." );
3256
3264
E->addDecorate (new SPIRVDecorateBankBitsINTELAttr (
3257
- E, getBankBitsFromStrings (I.second )));
3265
+ E, getLiteralsFromStrings (I.second )));
3258
3266
}
3259
3267
} break ;
3260
3268
case DecorationRegisterINTEL:
@@ -3315,7 +3323,32 @@ void addAnnotationDecorations(SPIRVEntry *E, DecorationsInfoVec &Decorations) {
3315
3323
E->addDecorate (I.first , Result);
3316
3324
}
3317
3325
} break ;
3318
-
3326
+ case DecorationLatencyControlLabelINTEL: {
3327
+ if (M->isAllowedToUseExtension (
3328
+ ExtensionID::SPV_INTEL_fpga_latency_control)) {
3329
+ M->getErrorLog ().checkError (
3330
+ I.second .size () == 1 , SPIRVEC_InvalidLlvmModule,
3331
+ " LatencyControlLabelINTEL requires exactly 1 extra operand" );
3332
+ SPIRVWord Label = 0 ;
3333
+ StringRef (I.second [0 ]).getAsInteger (10 , Label);
3334
+ E->addDecorate (
3335
+ new SPIRVDecorate (DecorationLatencyControlLabelINTEL, E, Label));
3336
+ }
3337
+ break ;
3338
+ }
3339
+ case DecorationLatencyControlConstraintINTEL: {
3340
+ if (M->isAllowedToUseExtension (
3341
+ ExtensionID::SPV_INTEL_fpga_latency_control)) {
3342
+ M->getErrorLog ().checkError (
3343
+ I.second .size () == 3 , SPIRVEC_InvalidLlvmModule,
3344
+ " LatencyControlConstraintINTEL requires exactly 3 extra operands" );
3345
+ auto Literals = getLiteralsFromStrings (I.second );
3346
+ E->addDecorate (
3347
+ new SPIRVDecorate (DecorationLatencyControlConstraintINTEL, E,
3348
+ Literals[0 ], Literals[1 ], Literals[2 ]));
3349
+ }
3350
+ break ;
3351
+ }
3319
3352
default :
3320
3353
// Other decorations are either not supported by the translator or
3321
3354
// handled in other places.
@@ -3364,7 +3397,7 @@ void addAnnotationDecorationsForStructMember(SPIRVEntry *E,
3364
3397
I.second .size () > 0 , SPIRVEC_InvalidLlvmModule,
3365
3398
" BankBitsINTEL requires at least one argument." );
3366
3399
E->addMemberDecorate (new SPIRVMemberDecorateBankBitsINTELAttr (
3367
- E, MemberNumber, getBankBitsFromStrings (I.second )));
3400
+ E, MemberNumber, getLiteralsFromStrings (I.second )));
3368
3401
break ;
3369
3402
case DecorationRegisterINTEL:
3370
3403
case DecorationSinglepumpINTEL:
@@ -3581,7 +3614,7 @@ static bool allowsApproxFunction(IntrinsicInst *II) {
3581
3614
cast<VectorType>(Ty)->getElementType ()->isFloatTy ()));
3582
3615
}
3583
3616
3584
- bool allowDecorateWithBufferLocationINTEL (IntrinsicInst *II) {
3617
+ bool allowDecorateWithBufferLocationOrLatencyControlINTEL (IntrinsicInst *II) {
3585
3618
SmallVector<Value *, 8 > UserList;
3586
3619
3587
3620
for (auto *Inst : II->users ()) {
@@ -4086,15 +4119,18 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
4086
4119
// because multiple accesses to the struct-held memory can require
4087
4120
// different LSU parameters.
4088
4121
addAnnotationDecorations (ResPtr, Decorations.MemoryAccessesVec );
4089
- if (allowDecorateWithBufferLocationINTEL (II))
4122
+ if (allowDecorateWithBufferLocationOrLatencyControlINTEL (II)) {
4090
4123
addAnnotationDecorations (ResPtr, Decorations.BufferLocationVec );
4124
+ addAnnotationDecorations (ResPtr, Decorations.LatencyControlVec );
4125
+ }
4091
4126
}
4092
4127
II->replaceAllUsesWith (II->getOperand (0 ));
4093
4128
} else {
4094
4129
// Memory accesses to a standalone pointer variable
4095
4130
auto *DecSubj = transValue (II->getArgOperand (0 ), BB);
4096
4131
if (Decorations.MemoryAccessesVec .empty () &&
4097
- Decorations.BufferLocationVec .empty ())
4132
+ Decorations.BufferLocationVec .empty () &&
4133
+ Decorations.LatencyControlVec .empty ())
4098
4134
DecSubj->addDecorate (new SPIRVDecorateUserSemanticAttr (
4099
4135
DecSubj, AnnotationString.c_str ()));
4100
4136
else {
@@ -4103,8 +4139,10 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
4103
4139
// loaded from the original pointer variable, and not the value
4104
4140
// accessed by the latter.
4105
4141
addAnnotationDecorations (DecSubj, Decorations.MemoryAccessesVec );
4106
- if (allowDecorateWithBufferLocationINTEL (II))
4142
+ if (allowDecorateWithBufferLocationOrLatencyControlINTEL (II)) {
4107
4143
addAnnotationDecorations (DecSubj, Decorations.BufferLocationVec );
4144
+ addAnnotationDecorations (DecSubj, Decorations.LatencyControlVec );
4145
+ }
4108
4146
}
4109
4147
II->replaceAllUsesWith (II->getOperand (0 ));
4110
4148
}
0 commit comments