brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 1e609a2 Raw
94 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "RuntimeLibcalls.h"10#include "llvm/TableGen/Error.h"11 12using namespace llvm;13 14RuntimeLibcalls::RuntimeLibcalls(const RecordKeeper &Records) {15  ArrayRef<const Record *> AllRuntimeLibcalls =16      Records.getAllDerivedDefinitions("RuntimeLibcall");17 18  RuntimeLibcallDefList.reserve(AllRuntimeLibcalls.size());19 20  size_t CallTypeEnumVal = 0;21  for (const Record *RuntimeLibcallDef : AllRuntimeLibcalls) {22    RuntimeLibcallDefList.emplace_back(RuntimeLibcallDef, CallTypeEnumVal++);23    Def2RuntimeLibcall[RuntimeLibcallDef] = &RuntimeLibcallDefList.back();24  }25 26  for (RuntimeLibcall &LibCall : RuntimeLibcallDefList)27    Def2RuntimeLibcall[LibCall.getDef()] = &LibCall;28 29  ArrayRef<const Record *> AllRuntimeLibcallImplsRaw =30      Records.getAllDerivedDefinitions("RuntimeLibcallImpl");31 32  SmallVector<const Record *, 1024> AllRuntimeLibcallImpls(33      AllRuntimeLibcallImplsRaw);34 35  // Sort by libcall impl name and secondarily by the enum name.36  sort(AllRuntimeLibcallImpls, [](const Record *A, const Record *B) {37    return std::pair(A->getValueAsString("LibCallFuncName"), A->getName()) <38           std::pair(B->getValueAsString("LibCallFuncName"), B->getName());39  });40 41  RuntimeLibcallImplDefList.reserve(AllRuntimeLibcallImpls.size());42 43  size_t LibCallImplEnumVal = 1;44  for (const Record *LibCallImplDef : AllRuntimeLibcallImpls) {45    RuntimeLibcallImplDefList.emplace_back(LibCallImplDef, Def2RuntimeLibcall,46                                           LibCallImplEnumVal++);47 48    const RuntimeLibcallImpl &LibCallImpl = RuntimeLibcallImplDefList.back();49    Def2RuntimeLibcallImpl[LibCallImplDef] = &LibCallImpl;50 51    if (LibCallImpl.isDefault()) {52      const RuntimeLibcall *Provides = LibCallImpl.getProvides();53      if (!Provides)54        PrintFatalError(LibCallImplDef->getLoc(),55                        "default implementations must provide a libcall");56      LibCallToDefaultImpl[Provides] = &LibCallImpl;57    }58  }59}60 61void LibcallPredicateExpander::expand(SetTheory &ST, const Record *Def,62                                      SetTheory::RecSet &Elts) {63  assert(Def->isSubClassOf("LibcallImpls"));64 65  SetTheory::RecSet TmpElts;66 67  ST.evaluate(Def->getValueInit("MemberList"), TmpElts, Def->getLoc());68 69  Elts.insert(TmpElts.begin(), TmpElts.end());70 71  AvailabilityPredicate AP(Def->getValueAsDef("AvailabilityPredicate"));72  const Record *CCClass = Def->getValueAsOptionalDef("CallingConv");73 74  // This is assuming we aren't conditionally applying a calling convention to75  // some subsets, and not another, but this doesn't appear to be used.76 77  for (const Record *LibcallImplDef : TmpElts) {78    const RuntimeLibcallImpl *LibcallImpl =79        Libcalls.getRuntimeLibcallImpl(LibcallImplDef);80    if (!AP.isAlwaysAvailable() || CCClass) {81      auto [It, Inserted] = Func2Preds.insert({LibcallImpl, {{}, CCClass}});82      if (!Inserted) {83        PrintError(84            Def,85            "combining nested libcall set predicates currently unhandled: '" +86                LibcallImpl->getLibcallFuncName() + "'");87      }88 89      It->second.first.push_back(AP.getDef());90      It->second.second = CCClass;91    }92  }93}94