@@ -2958,10 +2958,11 @@ struct AnnotationDecorations {
2958
2958
DecorationsInfoVec MemoryAttributesVec;
2959
2959
DecorationsInfoVec MemoryAccessesVec;
2960
2960
DecorationsInfoVec BufferLocationVec;
2961
+ DecorationsInfoVec LatencyControlVec;
2961
2962
2962
2963
bool empty () {
2963
2964
return (MemoryAttributesVec.empty () && MemoryAccessesVec.empty () &&
2964
- BufferLocationVec.empty ());
2965
+ BufferLocationVec.empty () && LatencyControlVec. empty () );
2965
2966
}
2966
2967
};
2967
2968
@@ -3095,8 +3096,8 @@ static bool tryParseAnnotationDecoValues(StringRef ValueStr,
3095
3096
return false ;
3096
3097
// Skip the , delimiter and go directly to the start of next value.
3097
3098
ValueStart = (++I) + 1 ;
3099
+ continue ;
3098
3100
}
3099
- continue ;
3100
3101
}
3101
3102
if (CurrentC == ' ,' ) {
3102
3103
// Since we are not currently in a string literal, comma denotes a
@@ -3131,7 +3132,6 @@ static bool tryParseAnnotationDecoValues(StringRef ValueStr,
3131
3132
AnnotationDecorations tryParseAnnotationString (SPIRVModule *BM,
3132
3133
StringRef AnnotatedCode) {
3133
3134
AnnotationDecorations Decorates;
3134
-
3135
3135
// Annotation string decorations are separated into {word} OR
3136
3136
// {word:value,value,...} blocks, where value is either a word (including
3137
3137
// numbers) or a quotation mark enclosed string.
@@ -3155,6 +3155,8 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3155
3155
ExtensionID::SPV_INTEL_fpga_memory_attributes);
3156
3156
const bool AllowFPGABufLoc =
3157
3157
BM->isAllowedToUseExtension (ExtensionID::SPV_INTEL_fpga_buffer_location);
3158
+ const bool AllowFPGALatencyControl =
3159
+ BM->isAllowedToUseExtension (ExtensionID::SPV_INTEL_fpga_latency_control);
3158
3160
3159
3161
bool ValidDecorationFound = false ;
3160
3162
DecorationsInfoVec DecorationsVec;
@@ -3178,6 +3180,12 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3178
3180
DecorationKind == DecorationBufferLocationINTEL) {
3179
3181
Decorates.BufferLocationVec .emplace_back (
3180
3182
static_cast <Decoration>(DecorationKind), std::move (DecValues));
3183
+ } else if (AllowFPGALatencyControl &&
3184
+ (DecorationKind == DecorationLatencyControlLabelINTEL ||
3185
+ DecorationKind ==
3186
+ DecorationLatencyControlConstraintINTEL)) {
3187
+ Decorates.LatencyControlVec .emplace_back (
3188
+ static_cast <Decoration>(DecorationKind), std::move (DecValues));
3181
3189
} else {
3182
3190
DecorationsVec.emplace_back (static_cast <Decoration>(DecorationKind),
3183
3191
std::move (DecValues));
@@ -3270,12 +3278,12 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
3270
3278
}
3271
3279
3272
3280
std::vector<SPIRVWord>
3273
- getBankBitsFromStrings (const std::vector<std::string> &BitsStrings ) {
3274
- std::vector<SPIRVWord> Bits (BitsStrings .size ());
3275
- for (size_t J = 0 ; J < BitsStrings .size (); ++J)
3276
- if (StringRef (BitsStrings [J]).getAsInteger (10 , Bits [J]))
3281
+ getLiteralsFromStrings (const std::vector<std::string> &Strings ) {
3282
+ std::vector<SPIRVWord> Literals (Strings .size ());
3283
+ for (size_t J = 0 ; J < Strings .size (); ++J)
3284
+ if (StringRef (Strings [J]).getAsInteger (10 , Literals [J]))
3277
3285
return {};
3278
- return Bits ;
3286
+ return Literals ;
3279
3287
}
3280
3288
3281
3289
void addAnnotationDecorations (SPIRVEntry *E, DecorationsInfoVec &Decorations) {
@@ -3321,7 +3329,7 @@ void addAnnotationDecorations(SPIRVEntry *E, DecorationsInfoVec &Decorations) {
3321
3329
I.second .size () > 0 , SPIRVEC_InvalidLlvmModule,
3322
3330
" BankBitsINTEL requires at least one argument." );
3323
3331
E->addDecorate (new SPIRVDecorateBankBitsINTELAttr (
3324
- E, getBankBitsFromStrings (I.second )));
3332
+ E, getLiteralsFromStrings (I.second )));
3325
3333
}
3326
3334
} break ;
3327
3335
case DecorationRegisterINTEL:
@@ -3382,7 +3390,32 @@ void addAnnotationDecorations(SPIRVEntry *E, DecorationsInfoVec &Decorations) {
3382
3390
E->addDecorate (I.first , Result);
3383
3391
}
3384
3392
} break ;
3385
-
3393
+ case DecorationLatencyControlLabelINTEL: {
3394
+ if (M->isAllowedToUseExtension (
3395
+ ExtensionID::SPV_INTEL_fpga_latency_control)) {
3396
+ M->getErrorLog ().checkError (
3397
+ I.second .size () == 1 , SPIRVEC_InvalidLlvmModule,
3398
+ " LatencyControlLabelINTEL requires exactly 1 extra operand" );
3399
+ SPIRVWord Label = 0 ;
3400
+ StringRef (I.second [0 ]).getAsInteger (10 , Label);
3401
+ E->addDecorate (
3402
+ new SPIRVDecorate (DecorationLatencyControlLabelINTEL, E, Label));
3403
+ }
3404
+ break ;
3405
+ }
3406
+ case DecorationLatencyControlConstraintINTEL: {
3407
+ if (M->isAllowedToUseExtension (
3408
+ ExtensionID::SPV_INTEL_fpga_latency_control)) {
3409
+ M->getErrorLog ().checkError (
3410
+ I.second .size () == 3 , SPIRVEC_InvalidLlvmModule,
3411
+ " LatencyControlConstraintINTEL requires exactly 3 extra operands" );
3412
+ auto Literals = getLiteralsFromStrings (I.second );
3413
+ E->addDecorate (
3414
+ new SPIRVDecorate (DecorationLatencyControlConstraintINTEL, E,
3415
+ Literals[0 ], Literals[1 ], Literals[2 ]));
3416
+ }
3417
+ break ;
3418
+ }
3386
3419
default :
3387
3420
// Other decorations are either not supported by the translator or
3388
3421
// handled in other places.
@@ -3431,7 +3464,7 @@ void addAnnotationDecorationsForStructMember(SPIRVEntry *E,
3431
3464
I.second .size () > 0 , SPIRVEC_InvalidLlvmModule,
3432
3465
" BankBitsINTEL requires at least one argument." );
3433
3466
E->addMemberDecorate (new SPIRVMemberDecorateBankBitsINTELAttr (
3434
- E, MemberNumber, getBankBitsFromStrings (I.second )));
3467
+ E, MemberNumber, getLiteralsFromStrings (I.second )));
3435
3468
break ;
3436
3469
case DecorationRegisterINTEL:
3437
3470
case DecorationSinglepumpINTEL:
@@ -3648,7 +3681,7 @@ static bool allowsApproxFunction(IntrinsicInst *II) {
3648
3681
cast<VectorType>(Ty)->getElementType ()->isFloatTy ()));
3649
3682
}
3650
3683
3651
- bool allowDecorateWithBufferLocationINTEL (IntrinsicInst *II) {
3684
+ bool allowDecorateWithBufferLocationOrLatencyControlINTEL (IntrinsicInst *II) {
3652
3685
SmallVector<Value *, 8 > UserList;
3653
3686
3654
3687
for (auto *Inst : II->users ()) {
@@ -4153,15 +4186,18 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
4153
4186
// because multiple accesses to the struct-held memory can require
4154
4187
// different LSU parameters.
4155
4188
addAnnotationDecorations (ResPtr, Decorations.MemoryAccessesVec );
4156
- if (allowDecorateWithBufferLocationINTEL (II))
4189
+ if (allowDecorateWithBufferLocationOrLatencyControlINTEL (II)) {
4157
4190
addAnnotationDecorations (ResPtr, Decorations.BufferLocationVec );
4191
+ addAnnotationDecorations (ResPtr, Decorations.LatencyControlVec );
4192
+ }
4158
4193
}
4159
4194
II->replaceAllUsesWith (II->getOperand (0 ));
4160
4195
} else {
4161
4196
// Memory accesses to a standalone pointer variable
4162
4197
auto *DecSubj = transValue (II->getArgOperand (0 ), BB);
4163
4198
if (Decorations.MemoryAccessesVec .empty () &&
4164
- Decorations.BufferLocationVec .empty ())
4199
+ Decorations.BufferLocationVec .empty () &&
4200
+ Decorations.LatencyControlVec .empty ())
4165
4201
DecSubj->addDecorate (new SPIRVDecorateUserSemanticAttr (
4166
4202
DecSubj, AnnotationString.c_str ()));
4167
4203
else {
@@ -4170,8 +4206,10 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
4170
4206
// loaded from the original pointer variable, and not the value
4171
4207
// accessed by the latter.
4172
4208
addAnnotationDecorations (DecSubj, Decorations.MemoryAccessesVec );
4173
- if (allowDecorateWithBufferLocationINTEL (II))
4209
+ if (allowDecorateWithBufferLocationOrLatencyControlINTEL (II)) {
4174
4210
addAnnotationDecorations (DecSubj, Decorations.BufferLocationVec );
4211
+ addAnnotationDecorations (DecSubj, Decorations.LatencyControlVec );
4212
+ }
4175
4213
}
4176
4214
II->replaceAllUsesWith (II->getOperand (0 ));
4177
4215
}
0 commit comments