|
37 | 37 | // or comparison predicate. These are used to create a hash to map instructions
|
38 | 38 | // to integers to be used in similarity matching in sequences of instructions
|
39 | 39 | //
|
| 40 | +// Terminology: |
| 41 | +// An IRSimilarityCandidate is a region of IRInstructionData (wrapped |
| 42 | +// Instructions), usually used to denote a region of similarity has been found. |
| 43 | +// |
40 | 44 | //===----------------------------------------------------------------------===//
|
41 | 45 |
|
42 | 46 | #ifndef LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
|
@@ -386,6 +390,137 @@ struct IRInstructionMapper {
|
386 | 390 | InstructionClassification InstClassifier;
|
387 | 391 | };
|
388 | 392 |
|
| 393 | +/// This is a class that wraps a range of IRInstructionData from one point to |
| 394 | +/// another in the vector of IRInstructionData, which is a region of the |
| 395 | +/// program. It is also responsible for defining the structure within this |
| 396 | +/// region of instructions. |
| 397 | +/// |
| 398 | +/// The structure of a region is defined through a value numbering system |
| 399 | +/// assigned to each unique value in a region at the creation of the |
| 400 | +/// IRSimilarityCandidate. |
| 401 | +/// |
| 402 | +/// For example, for each Instruction we add a mapping for each new |
| 403 | +/// value seen in that Instruction. |
| 404 | +/// IR: Mapping Added: |
| 405 | +/// %add1 = add i32 %a, c1 %add1 -> 3, %a -> 1, c1 -> 2 |
| 406 | +/// %add2 = add i32 %a, %1 %add2 -> 4 |
| 407 | +/// %add3 = add i32 c2, c1 %add3 -> 6, c2 -> 5 |
| 408 | +/// |
| 409 | +/// We can compare IRSimilarityCandidates against one another. |
| 410 | +/// The \ref isSimilar function compares each IRInstructionData against one |
| 411 | +/// another and if we have the same sequences of IRInstructionData that would |
| 412 | +/// create the same hash, we have similar IRSimilarityCandidates. |
| 413 | +class IRSimilarityCandidate { |
| 414 | +private: |
| 415 | + /// The start index of this IRSimilarityCandidate in the instruction list. |
| 416 | + unsigned StartIdx = 0; |
| 417 | + |
| 418 | + /// The number of instructions in this IRSimilarityCandidate. |
| 419 | + unsigned Len = 0; |
| 420 | + |
| 421 | + /// The first instruction in this IRSimilarityCandidate. |
| 422 | + IRInstructionData *FirstInst = nullptr; |
| 423 | + |
| 424 | + /// The last instruction in this IRSimilarityCandidate. |
| 425 | + IRInstructionData *LastInst = nullptr; |
| 426 | + |
| 427 | + /// Global Value Numbering structures |
| 428 | + /// @{ |
| 429 | + /// Stores the mapping of the value to the number assigned to it in the |
| 430 | + /// IRSimilarityCandidate. |
| 431 | + DenseMap<Value *, unsigned> ValueToNumber; |
| 432 | + /// Stores the mapping of the number to the value assigned this number. |
| 433 | + DenseMap<unsigned, Value *> NumberToValue; |
| 434 | + /// @} |
| 435 | + |
| 436 | +public: |
| 437 | + /// \param StartIdx - The starting location of the region. |
| 438 | + /// \param StartIdx - The length of the region. |
| 439 | + /// \param FirstInstIt - The starting IRInstructionData of the region. |
| 440 | + /// \param LastInstIt - The ending IRInstructionData of the region. |
| 441 | + IRSimilarityCandidate(unsigned StartIdx, unsigned Len, |
| 442 | + IRInstructionData *FirstInstIt, |
| 443 | + IRInstructionData *LastInstIt); |
| 444 | + |
| 445 | + /// \param A - The first IRInstructionCandidate to compare. |
| 446 | + /// \param B - The second IRInstructionCandidate to compare. |
| 447 | + /// \returns True when every IRInstructionData in \p A is similar to every |
| 448 | + /// IRInstructionData in \p B. |
| 449 | + static bool isSimilar(const IRSimilarityCandidate &A, |
| 450 | + const IRSimilarityCandidate &B); |
| 451 | + /// Compare the start and end indices of the two IRSimilarityCandidates for |
| 452 | + /// whether they overlap. If the start instruction of one |
| 453 | + /// IRSimilarityCandidate is less than the end instruction of the other, and |
| 454 | + /// the start instruction of one is greater than the start instruction of the |
| 455 | + /// other, they overlap. |
| 456 | + /// |
| 457 | + /// \returns true if the IRSimilarityCandidates do not have overlapping |
| 458 | + /// instructions. |
| 459 | + static bool overlap(const IRSimilarityCandidate &A, |
| 460 | + const IRSimilarityCandidate &B); |
| 461 | + |
| 462 | + /// \returns the number of instructions in this Candidate. |
| 463 | + unsigned getLength() const { return Len; } |
| 464 | + |
| 465 | + /// \returns the start index of this IRSimilarityCandidate. |
| 466 | + unsigned getStartIdx() const { return StartIdx; } |
| 467 | + |
| 468 | + /// \returns the end index of this IRSimilarityCandidate. |
| 469 | + unsigned getEndIdx() const { return StartIdx + Len - 1; } |
| 470 | + |
| 471 | + /// \returns The first IRInstructionData. |
| 472 | + IRInstructionData *front() const { return FirstInst; } |
| 473 | + /// \returns The last IRInstructionData. |
| 474 | + IRInstructionData *back() const { return LastInst; } |
| 475 | + |
| 476 | + /// \returns The first Instruction. |
| 477 | + Instruction *frontInstruction() { return FirstInst->Inst; } |
| 478 | + /// \returns The last Instruction |
| 479 | + Instruction *backInstruction() { return LastInst->Inst; } |
| 480 | + |
| 481 | + /// \returns The BasicBlock the IRSimilarityCandidate starts in. |
| 482 | + BasicBlock *getStartBB() { return FirstInst->Inst->getParent(); } |
| 483 | + /// \returns The BasicBlock the IRSimilarityCandidate ends in. |
| 484 | + BasicBlock *getEndBB() { return LastInst->Inst->getParent(); } |
| 485 | + |
| 486 | + /// \returns The Function that the IRSimilarityCandidate is located in. |
| 487 | + Function *getFunction() { return getStartBB()->getParent(); } |
| 488 | + |
| 489 | + /// Finds the positive number associated with \p V if it has been mapped. |
| 490 | + /// \param [in] V - the Value to find. |
| 491 | + /// \returns The positive number corresponding to the value. |
| 492 | + /// \returns None if not present. |
| 493 | + Optional<unsigned> getGVN(Value *V) { |
| 494 | + assert(V != nullptr && "Value is a nullptr?"); |
| 495 | + DenseMap<Value *, unsigned>::iterator VNIt = ValueToNumber.find(V); |
| 496 | + if (VNIt == ValueToNumber.end()) |
| 497 | + return None; |
| 498 | + return VNIt->second; |
| 499 | + } |
| 500 | + |
| 501 | + /// Finds the Value associate with \p Num if it exists. |
| 502 | + /// \param [in] Num - the number to find. |
| 503 | + /// \returns The Value associated with the number. |
| 504 | + /// \returns None if not present. |
| 505 | + Optional<Value *> fromGVN(unsigned Num) { |
| 506 | + DenseMap<unsigned, Value *>::iterator VNIt = NumberToValue.find(Num); |
| 507 | + if (VNIt == NumberToValue.end()) |
| 508 | + return None; |
| 509 | + assert(VNIt->second != nullptr && "Found value is a nullptr!"); |
| 510 | + return VNIt->second; |
| 511 | + } |
| 512 | + |
| 513 | + /// \param RHS -The IRSimilarityCandidate to compare against |
| 514 | + /// \returns true if the IRSimilarityCandidate is occurs after the |
| 515 | + /// IRSimilarityCandidate in the program. |
| 516 | + bool operator<(const IRSimilarityCandidate &RHS) const { |
| 517 | + return getStartIdx() > RHS.getStartIdx(); |
| 518 | + } |
| 519 | + |
| 520 | + using iterator = IRInstructionDataList::iterator; |
| 521 | + iterator begin() const { return iterator(front()); } |
| 522 | + iterator end() const { return std::next(iterator(back())); } |
| 523 | +}; |
389 | 524 | } // end namespace IRSimilarity
|
390 | 525 | } // end namespace llvm
|
391 | 526 |
|
|
0 commit comments