rusty_v8 0.3.6-debug4

Rust bindings to V8
Documentation
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Analysis/CallGraph.h"

#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace llvm;

static unsigned kGCAddressSpace = 1;

void MaybeStatepointFunction(Function* F) {
  if (F->hasFnAttribute("statepoint")) {
    if (F->hasFnAttribute("no-statepoint"))
      return;

    F->setGC("statepoint-example");
  }
}

namespace {
struct RegisterGcFunctions : public ModulePass {
  static char ID;
  RegisterGcFunctions() : ModulePass(ID) {}

  bool runOnModule(Module& M) override {
    auto GA = M.getNamedGlobal("llvm.global.annotations");
    if (GA) {
      auto a = cast<ConstantArray>(GA->getOperand(0));
      for (int i = 0; i < a->getNumOperands(); i++) {
        auto e = cast<ConstantStruct>(a->getOperand(i));

        if (auto F = dyn_cast<Function>(e->getOperand(0)->getOperand(0))) {
          auto Anno = cast<ConstantDataArray>(
                          cast<GlobalVariable>(e->getOperand(1)->getOperand(0))
                              ->getOperand(0))
                          ->getAsCString();
          F->addFnAttr(Anno);
        }
      }
    }

    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      MaybeStatepointFunction(&*F);
    }

    return false;
  }
};

char RegisterGcFunctions::ID;
}  // end of anonymous namespace

static RegisterPass<RegisterGcFunctions> X("register-gc-fns",
                                           "Register GC Functions",
                                           false /* Only looks at CFG */,
                                           true /* Analysis Pass */);

static RegisterStandardPasses Y(PassManagerBuilder::EP_ModuleOptimizerEarly,
                                [](const PassManagerBuilder& Builder,
                                   legacy::PassManagerBase& PM) {
                                  PM.add(new RegisterGcFunctions());
                                });