[llvm] [TableGen] Rework `EmitIntrinsicToBuiltinMap` (PR #104681)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 20:57:29 PDT 2024


jurahul wrote:

For comparison, here's the old and new version of `getIntrinsicForMSBuiltin`:

old version:

```C++
// Get the LLVM intrinsic that corresponds to a builtin.
// This is used by the C front-end.  The builtin name is passed
// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed
// in as TargetPrefix. The result is assigned to 'IntrinsicID'.
#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
Intrinsic::ID Intrinsic::getIntrinsicForMSBuiltin(const char *TargetPrefixStr, StringRef BuiltinNameStr) {
  static constexpr char BuiltinNames[] = {
  '_', '_', 'd', 'm', 'b', '\000', '_', '_', 'd', 's', 'b', '\000', '_', '_', 'i',
  's', 'b', '\000', '_', 'M', 'o', 'v', 'e', 'F', 'r', 'o', 'm', 'C', 'o', 'p',
  'r', 'o', 'c', 'e', 's', 's', 'o', 'r', '\000', '_', 'M', 'o', 'v', 'e', 'F',
  'r', 'o', 'm', 'C', 'o', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r', '2',
  '\000',
  };

  struct BuiltinEntry {
    Intrinsic::ID IntrinID;
    unsigned StrTabOffset;
    const char *getName() const {
      return &BuiltinNames[StrTabOffset];
    }
    bool operator<(StringRef RHS) const {
      return strncmp(getName(), RHS.data(), RHS.size()) < 0;
    }
  };
  StringRef TargetPrefix(TargetPrefixStr);

  if (TargetPrefix == "aarch64") {
    static constexpr BuiltinEntry aarch64Names[] = {
      {Intrinsic::aarch64_dmb, 0}, // __dmb
      {Intrinsic::aarch64_dsb, 6}, // __dsb
      {Intrinsic::aarch64_isb, 12}, // __isb
    };
    auto I = std::lower_bound(std::begin(aarch64Names),
                              std::end(aarch64Names),
                              BuiltinNameStr);
    if (I != std::end(aarch64Names) &&
        I->getName() == BuiltinNameStr)
      return I->IntrinID;
  }
  if (TargetPrefix == "arm") {
    static constexpr BuiltinEntry armNames[] = {
      {Intrinsic::arm_mrc, 18}, // _MoveFromCoprocessor
      {Intrinsic::arm_mrc2, 39}, // _MoveFromCoprocessor2
      {Intrinsic::arm_dmb, 0}, // __dmb
      {Intrinsic::arm_dsb, 6}, // __dsb
      {Intrinsic::arm_isb, 12}, // __isb
    };
    auto I = std::lower_bound(std::begin(armNames),
                              std::end(armNames),
                              BuiltinNameStr);
    if (I != std::end(armNames) &&
        I->getName() == BuiltinNameStr)
      return I->IntrinID;
  }
  return Intrinsic::not_intrinsic;
}
#endif
```

new version:

```C++
// Get the LLVM intrinsic that corresponds to a builtin. This is used by the
// C front-end. The builtin name is passed in as BuiltinName, and a target
// prefix (e.g. 'ppc') is passed in as TargetPrefix.
#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
Intrinsic::ID
Intrinsic::getIntrinsicForMSBuiltin(StringRef TargetPrefix, 
                                      StringRef BuiltinName) {
  using namespace Intrinsic;
  static constexpr char BuiltinNames[] = {
  'd', 'm', 'b', '\000', 'd', 's', 'b', '\000', 'i', 's', 'b', '\000', 'M', 'o', 'v',
  'e', 'F', 'r', 'o', 'm', 'C', 'o', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o',
  'r', '\000', 'M', 'o', 'v', 'e', 'F', 'r', 'o', 'm', 'C', 'o', 'p', 'r', 'o',
  'c', 'e', 's', 's', 'o', 'r', '2', '\000', '_', 'd', 'm', 'b', '\000', '_', 'd',
  's', 'b', '\000', '_', 'i', 's', 'b', '\000',
  };


  struct BuiltinEntry {
    constexpr BuiltinEntry(ID IntrinsicID, unsigned Offset)
        : IntrinsicID(IntrinsicID), Suffix(&BuiltinNames[Offset]) {}
    ID IntrinsicID;
    StringRef Suffix;
    bool operator<(StringRef RHS) const { return Suffix < RHS; }
  };

  // Builtins for aarch64.
  static constexpr BuiltinEntry aarch64Names[] = {
    {aarch64_dmb, 0}, // __dmb
    {aarch64_dsb, 4}, // __dsb
    {aarch64_isb, 8}, // __isb
  }; // aarch64Names

  // Builtins for arm.
  static constexpr BuiltinEntry armNames[] = {
    {arm_mrc, 12}, // _MoveFromCoprocessor
    {arm_mrc2, 32}, // _MoveFromCoprocessor2
    {arm_dmb, 53}, // __dmb
    {arm_dsb, 58}, // __dsb
    {arm_isb, 63}, // __isb
  }; // armNames


  struct TargetEntry {
    StringRef TargetPrefix;
    ArrayRef<BuiltinEntry> Names;
    StringRef CommonPrefix;
    bool operator<(StringRef RHS) const {
      return TargetPrefix < RHS;
    };
  };
  static constexpr TargetEntry TargetTable[] = {
    {"aarch64", aarch64Names, "__"},
    {"arm", armNames, "_"},
  };

  auto TI = lower_bound(TargetTable, TargetPrefix);
  if (TI == std::end(TargetTable) || TI->TargetPrefix != TargetPrefix)
    return not_intrinsic;
  // This is the last use of BuiltinName, so no need to copy before using it in
  // consume_front.
  if (!BuiltinName.consume_front(TI->CommonPrefix))
    return not_intrinsic;
  auto II = lower_bound(TI->Names, BuiltinName);
  if (II == std::end(TI->Names) || II->Suffix != BuiltinName)
    return not_intrinsic;
  return II->IntrinsicID;
}
#endif // GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
```


https://github.com/llvm/llvm-project/pull/104681


More information about the llvm-commits mailing list