LLVM: lib/IR/VFABIDemangler.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17#include

18

19using namespace llvm;

20

21#define DEBUG_TYPE "vfabi-demangler"

22

23

24

25namespace {

26

27enum class ParseRet {

28 OK,

29 None,

30 Error

31};

32}

33

34

35

36

38 if (MangledName.empty())

39 return ParseRet::Error;

40

43 } else {

53 MangledName = MangledName.drop_front(1);

54 }

55

56 return ParseRet::OK;

57}

58

59

60

61

64 IsMasked = true;

65 return ParseRet::OK;

66 }

67

69 IsMasked = false;

70 return ParseRet::OK;

71 }

72

73 return ParseRet::Error;

74}

75

76

77

78

79

80

82 std::pair<unsigned, bool> &ParsedVF) {

84

86 LLVM_DEBUG(dbgs() << "Vector function variant declared with scalable VF "

87 << "but ISA supported for SVE and RVV only\n");

88 return ParseRet::Error;

89 }

90

91

92

93

94 ParsedVF = {0, true};

95 return ParseRet::OK;

96 }

97

98 unsigned VF = 0;

100 return ParseRet::Error;

101

102

103 if (VF == 0)

104 return ParseRet::Error;

105

106 ParsedVF = {VF, false};

107 return ParseRet::OK;

108}

109

110

111

112

113

114

115

116

117

118

119

120

121

128 return ParseRet::Error;

129 return ParseRet::OK;

130 }

131

132 return ParseRet::None;

133}

134

135

136

137

138

139

140

141

142

143

144

145

148 int &StepOrPos) {

149 ParseRet Ret;

150

151

153 if (Ret != ParseRet::None)

154 return Ret;

155

156

158 if (Ret != ParseRet::None)

159 return Ret;

160

161

163 if (Ret != ParseRet::None)

164 return Ret;

165

166

168 if (Ret != ParseRet::None)

169 return Ret;

170

171 return ParseRet::None;

172}

173

174

175

176

177

178

179

180

181

182

183

184

185

188 int &LinearStep,

192 const bool Negate = ParseString.consume_front("n");

194 LinearStep = 1;

195 if (Negate)

196 LinearStep *= -1;

197 return ParseRet::OK;

198 }

199

200 return ParseRet::None;

201}

202

203

204

205

206

207

208

209

210

211

214 int &StepOrPos) {

215

217 ParseRet::OK)

218 return ParseRet::OK;

219

220

222 ParseRet::OK)

223 return ParseRet::OK;

224

225

227 ParseRet::OK)

228 return ParseRet::OK;

229

230

232 ParseRet::OK)

233 return ParseRet::OK;

234

235 return ParseRet::None;

236}

237

238

239

240

241

242

243

244

245

247 int &StepOrPos) {

250 StepOrPos = 0;

251 return ParseRet::OK;

252 }

253

256 StepOrPos = 0;

257 return ParseRet::OK;

258 }

259

260 const ParseRet HasLinearRuntime =

262 if (HasLinearRuntime != ParseRet::None)

263 return HasLinearRuntime;

264

265 const ParseRet HasLinearCompileTime =

267 if (HasLinearCompileTime != ParseRet::None)

268 return HasLinearCompileTime;

269

270 return ParseRet::None;

271}

272

273

274

275

276

277

278

279

280

283

286 return ParseRet::Error;

287

289 return ParseRet::Error;

290

291 Alignment = Align(Val);

292

293 return ParseRet::OK;

294 }

295

296 return ParseRet::None;

297}

298

299

300

301

302

303

304

306 const Type *Ty) {

308 "Scalable VF decoding only implemented for SVE and RVV\n");

309

310 if (Ty->isIntegerTy(64) || Ty->isDoubleTy() || Ty->isPointerTy())

312 if (Ty->isIntegerTy(32) || Ty->isFloatTy())

314 if (Ty->isIntegerTy(16) || Ty->is16bitFPTy())

316 if (Ty->isIntegerTy(8))

318

319 return std::nullopt;

320}

321

322

323

324static std::optional

327

330 for (auto &Param : Params) {

331

332

334 Type *PTy = Signature->getParamType(Param.ParamPos);

335

337

338

339 if (!EC)

340 return std::nullopt;

341

342

344 MinEC = *EC;

345 }

346 }

347

348

349 Type *RetTy = Signature->getReturnType();

351

354 return std::nullopt;

355

358

359

360 if (!ReturnEC)

361 return std::nullopt;

363 MinEC = *ReturnEC;

364 }

365 }

366

367

368

369

370

371 if (MinEC.getKnownMinValue() < std::numeric_limits::max())

372 return MinEC;

373

374 return std::nullopt;

375}

376

377

378

381 const StringRef OriginalName = MangledName;

382

383

384

385 StringRef VectorName = MangledName;

386

387

389 return std::nullopt;

390

391

392

394 if (tryParseISA(MangledName, ISA) != ParseRet::OK)

395 return std::nullopt;

396

397

398 bool IsMasked;

399 if (tryParseMask(MangledName, IsMasked) != ParseRet::OK)

400 return std::nullopt;

401

402

403 std::pair<unsigned, bool> ParsedVF;

404 if (tryParseVLEN(MangledName, ISA, ParsedVF) != ParseRet::OK)

405 return std::nullopt;

406

407

408 ParseRet ParamFound;

410 do {

411 const unsigned ParameterPos = Parameters.size();

413 int StepOrPos;

415

416

417 if (ParamFound == ParseRet::Error)

418 return std::nullopt;

419

420 if (ParamFound == ParseRet::OK) {

422

423 const ParseRet AlignFound = tryParseAlign(MangledName, Alignment);

424

425 if (AlignFound == ParseRet::Error)

426 return std::nullopt;

427

428

429 Parameters.push_back({ParameterPos, PKind, StepOrPos, Alignment});

430 }

431 } while (ParamFound == ParseRet::OK);

432

433

434

435 if (Parameters.empty())

436 return std::nullopt;

437

438

439

440 if (Parameters.size() != FTy->getNumParams())

441 return std::nullopt;

442

443

444

445

446

447

448 std::optional EC;

449 if (ParsedVF.second) {

451 if (!EC)

452 return std::nullopt;

453 } else

455

456

457

459 return std::nullopt;

460

461

462

464 MangledName.take_while([](char In) { return In != '('; });

465

466 if (ScalarName.empty())

467 return std::nullopt;

468

469

470 MangledName = MangledName.ltrim(ScalarName);

471

474 return std::nullopt;

475

476 VectorName = MangledName;

477

478 if (VectorName.empty())

479 return std::nullopt;

480 }

481

482

483

484 if (ISA == VFISAKind::LLVM && VectorName == OriginalName)

485 return std::nullopt;

486

487

488

489 if (IsMasked) {

490 const unsigned Pos = Parameters.size();

492 }

493

494

495

496

497

498

499 const auto NGlobalPreds =

502 });

503 assert(NGlobalPreds < 2 && "Cannot have more than one global predicate.");

504 if (NGlobalPreds)

506 "The global predicate must be the last parameter");

507

508 const VFShape Shape({*EC, Parameters});

509 return VFInfo({Shape, std::string(ScalarName), std::string(VectorName), ISA});

510}

511

525

527 return ParamKind;

528

529

530 llvm_unreachable("This fuction should be invoken only on parameters"

531 " that have a textual representation in the mangled name"

532 " of the Vector Function ABI");

533}

534

539 return;

540

542 S.split(ListAttr, ",");

543

545 std::optional Info =

548 LLVM_DEBUG(dbgs() << "VFABI: Adding mapping '" << S << "' for " << CI

549 << "\n");

550 VariantMappings.push_back(std::string(S));

551 } else

552 LLVM_DEBUG(dbgs() << "VFABI: Invalid mapping '" << S << "'\n");

553 }

554}

555

558

561 int ScalarParamIndex = 0;

562 for (auto VFParam : Info.Shape.Parameters) {

567 continue;

568 }

569

570 Type *OperandTy = ScalarFTy->getParamType(ScalarParamIndex++);

574 }

575

577 if (!RetTy->isVoidTy())

580}

581

584 if (VariantMappings.empty())

585 return;

586

589 for (const std::string &VariantMapping : VariantMappings)

590 Out << VariantMapping << ",";

591

592 assert(!Buffer.str().empty() && "Must have at least one char.");

594

596#ifndef NDEBUG

597 for (const std::string &VariantMapping : VariantMappings) {

598 LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");

599 std::optional VI =

601 assert(VI && "Cannot add an invalid VFABI name.");

602 assert(M->getNamedValue(VI->VectorName) &&

603 "Cannot add variant to attribute: "

604 "vector function declaration is missing.");

605 }

606#endif

609}

610

612 for (unsigned Pos = 0, NumParams = Parameters.size(); Pos < NumParams;

613 ++Pos) {

614 assert(Parameters[Pos].ParamPos == Pos && "Broken parameter list.");

615

617 default:

618 break;

623

624 if (Parameters[Pos].LinearStepOrPos == 0)

625 return false;

626 break;

631

632

633 if (Parameters[Pos].LinearStepOrPos >= int(NumParams))

634 return false;

635

638 return false;

639

640 if (Parameters[Pos].LinearStepOrPos == int(Pos))

641 return false;

642 break;

644

645

646 for (unsigned NextPos = Pos + 1; NextPos < NumParams; ++NextPos)

648 return false;

649 break;

650 }

651 }

652 return true;

653}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

Module.h This file contains the declarations for the Module class.

This file implements a set that has insertion order iteration characteristics.

This file defines the SmallString class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static ParseRet tryParseVLEN(StringRef &ParseString, VFISAKind ISA, std::pair< unsigned, bool > &ParsedVF)

Extract the information from the mangled string, and sets ParsedVF accordingly.

Definition VFABIDemangler.cpp:81

static ParseRet tryParseMask(StringRef &MangledName, bool &IsMasked)

Extracts the information from the mangled string, and sets IsMasked accordingly.

Definition VFABIDemangler.cpp:62

static ParseRet tryParseParameter(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos)

Looks into the part of the mangled name in search for valid paramaters at the beginning ...

Definition VFABIDemangler.cpp:246

static std::optional< ElementCount > getElementCountForTy(const VFISAKind ISA, const Type *Ty)

Definition VFABIDemangler.cpp:305

static std::optional< ElementCount > getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA, const SmallVectorImpl< VFParameter > &Params)

Definition VFABIDemangler.cpp:325

static ParseRet tryParseLinearTokenWithRuntimeStep(StringRef &ParseString, VFParamKind &PKind, int &Pos, const StringRef Token)

The function looks for the following strings at the beginning of the input string ParseString:

Definition VFABIDemangler.cpp:122

static ParseRet tryParseLinearWithRuntimeStep(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos)

The function looks for the following string at the beginning of the input string ParseString:

Definition VFABIDemangler.cpp:146

static ParseRet tryParseISA(StringRef &MangledName, VFISAKind &ISA)

Extracts the information from the mangled string, and sets the ISA accordingly.

Definition VFABIDemangler.cpp:37

static ParseRet tryParseCompileTimeLinearToken(StringRef &ParseString, VFParamKind &PKind, int &LinearStep, const StringRef Token)

The function looks for the following strings at the beginning of the input string ParseString:

Definition VFABIDemangler.cpp:186

static ParseRet tryParseAlign(StringRef &ParseString, Align &Alignment)

Looks into the part of the mangled name in search of a valid 'aligned' clause.

Definition VFABIDemangler.cpp:281

static ParseRet tryParseLinearWithCompileTimeStep(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos)

The function looks for the following strings at the beginning of the input string ParseString:

Definition VFABIDemangler.cpp:212

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool empty() const

empty - Check if the array is empty.

static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)

Return a uniquified Attribute object.

LLVM_ABI StringRef getValueAsString() const

Return the attribute's value as a string.

void addFnAttr(Attribute::AttrKind Kind)

Adds the attribute to the function.

Attribute getFnAttr(StringRef Kind) const

Get the attribute of a given kind for the function.

FunctionType * getFunctionType() const

This class represents a function call, abstracting a target machine's calling convention.

static constexpr ElementCount getScalable(ScalarTy MinVal)

static constexpr ElementCount getFixed(ScalarTy MinVal)

Lightweight error class with error context and mandatory checking.

Class to represent function types.

unsigned getNumParams() const

Return the number of fixed parameters this function type requires.

Type * getParamType(unsigned i) const

Parameter type accessors.

Type * getReturnType() const

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

LLVM_ABI const Module * getModule() const

Return the module owning the function this instruction belongs to or nullptr it the function does not...

A Module instance is used to store all the information related to an LLVM module.

Function * getFunction(StringRef Name) const

Look up the specified function in the module symbol table.

A vector that has set insertion semantics.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringRef str() const

Explicit conversion to StringRef.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

bool consume_back(StringRef Suffix)

Returns true if this StringRef has the given suffix and removes that suffix.

bool consumeInteger(unsigned Radix, T &Result)

Parse the current string as an integer of the specified radix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef take_while(function_ref< bool(char)> F) const

Return the longest prefix of 'this' such that every character in the prefix satisfies the given predi...

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

StringRef ltrim(char Char) const

Return string with consecutive Char characters starting from the the left removed.

bool consume_front(StringRef Prefix)

Returns true if this StringRef has the given prefix and removes that prefix.

StringRef take_front(size_t N=1) const

Return a StringRef equal to 'this' but with only the first N elements remaining.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

Class to represent struct types.

The instances of the Type class are immutable: once they are created, they are never changed.

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)

bool isVoidTy() const

Return true if this is 'void'.

Base class of all SIMD vector types.

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)

constexpr ScalarTy getKnownMinValue() const

Returns the minimum value this quantity can represent.

A raw_ostream that writes to an SmallVector or SmallString.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

static constexpr char const * MappingsAttrName

LLVM_ABI std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)

Function to construct a VFInfo out of a mangled names in the following format:

Definition VFABIDemangler.cpp:379

LLVM_ABI FunctionType * createFunctionType(const VFInfo &Info, const FunctionType *ScalarFTy)

Constructs a FunctionType by applying vector function information to the type of a matching scalar fu...

Definition VFABIDemangler.cpp:556

LLVM_ABI void getVectorVariantNames(const CallInst &CI, SmallVectorImpl< std::string > &VariantMappings)

Populates a set of strings representing the Vector Function ABI variants associated to the CallInst C...

Definition VFABIDemangler.cpp:535

LLVM_ABI void setVectorVariantNames(CallInst *CI, ArrayRef< std::string > VariantMappings)

Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.

Definition VFABIDemangler.cpp:582

LLVM_ABI VFParamKind getVFParamKindFromString(const StringRef Token)

Retrieve the VFParamKind from a string token.

Definition VFABIDemangler.cpp:512

static constexpr char const * _LLVM_

LLVM Internal VFABI ISA token for vector functions.

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

bool isUnpackedStructLiteral(StructType *StructTy)

constexpr from_range_t from_range

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

Type * toVectorizedTy(Type *Ty, ElementCount EC)

A helper for converting to vectorized types.

VFISAKind

Describes the type of Instruction Set Architecture.

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

ArrayRef< Type * > getContainedTypes(Type *const &Ty)

Returns the types contained in Ty.

VFParamKind

Describes the type of Parameters.

This struct is a compact representation of a valid (non-zero power of two) alignment.

Holds the VFShape for a specific scalar to vector function mapping.

Encapsulates information needed to describe a parameter.

Contains the information about the kind of vectorization available.

LLVM_ABI bool hasValidParameterList() const

Validation check on the Parameters in the VFShape.

Definition VFABIDemangler.cpp:611

SmallVector< VFParameter, 8 > Parameters