Commit fefb77d0 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Adding first prototype xacc compiler built on Clang/LLVM


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 4f890c51
......@@ -94,6 +94,13 @@ if(PYTHON_INCLUDE_DIR)
add_subdirectory(python)
endif()
find_package(Clang 9.0.0)
if (CLANG_FOUND)
add_subdirectory(tools)
configure_file(${CMAKE_SOURCE_DIR}/scripts/xacc.in
${CMAKE_BINARY_DIR}/scripts/xacc)
install(PROGRAMS ${CMAKE_BINARY_DIR}/scripts/xacc DESTINATION bin)
endif()
# Install the config file for external projects to use
# This is cool, users just add find_package(XACC REQUIRED) to
......
# Detect Clang libraries
#
# Defines the following variables:
# CLANG_FOUND - True if Clang was found
# CLANG_INCLUDE_DIRS - Where to find Clang includes
# CLANG_LIBRARY_DIRS - Where to find Clang libraries
#
# CLANG_LIBCLANG_LIB - Libclang C library
#
# CLANG_CLANGFRONTEND_LIB - Clang Frontend (C++) Library
# CLANG_CLANGDRIVER_LIB - Clang Driver (C++) Library
# ...
#
# CLANG_LIBS - All the Clang C++ libraries
#
# Uses the same include and library paths detected by FindLLVM.cmake
#
# See http://clang.llvm.org/docs/InternalsManual.html for full list of libraries
#=============================================================================
# Copyright 2014-2015 Kevin Funk <kfunk@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if (${Clang_FIND_REQUIRED})
find_package(LLVM ${Clang_FIND_VERSION} REQUIRED)
else ()
find_package(LLVM ${Clang_FIND_VERSION})
endif ()
set(CLANG_FOUND FALSE)
if (LLVM_FOUND AND LLVM_LIBRARY_DIRS)
macro(FIND_AND_ADD_CLANG_LIB _libname_)
string(TOUPPER ${_libname_} _prettylibname_)
find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} HINTS ${LLVM_LIBRARY_DIRS})
if(CLANG_${_prettylibname_}_LIB)
set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_prettylibname_}_LIB})
endif()
endmacro(FIND_AND_ADD_CLANG_LIB)
# note: On Windows there's 'libclang.dll' instead of 'clang.dll' -> search for 'libclang', too
find_library(CLANG_LIBCLANG_LIB NAMES clang libclang HINTS ${LLVM_LIBRARY_DIRS}) # LibClang: high-level C interface
FIND_AND_ADD_CLANG_LIB(clangFrontend)
FIND_AND_ADD_CLANG_LIB(clangDriver)
FIND_AND_ADD_CLANG_LIB(clangCodeGen)
FIND_AND_ADD_CLANG_LIB(clangSema)
FIND_AND_ADD_CLANG_LIB(clangChecker)
FIND_AND_ADD_CLANG_LIB(clangAnalysis)
FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend)
FIND_AND_ADD_CLANG_LIB(clangRewrite)
FIND_AND_ADD_CLANG_LIB(clangAST)
FIND_AND_ADD_CLANG_LIB(clangASTMatchers)
FIND_AND_ADD_CLANG_LIB(clangParse)
FIND_AND_ADD_CLANG_LIB(clangLex)
FIND_AND_ADD_CLANG_LIB(clangBasic)
FIND_AND_ADD_CLANG_LIB(clangARCMigrate)
FIND_AND_ADD_CLANG_LIB(clangEdit)
FIND_AND_ADD_CLANG_LIB(clangFrontendTool)
FIND_AND_ADD_CLANG_LIB(clangRewrite)
FIND_AND_ADD_CLANG_LIB(clangSerialization)
FIND_AND_ADD_CLANG_LIB(clangTooling)
FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers)
FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore)
FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend)
FIND_AND_ADD_CLANG_LIB(clangSema)
FIND_AND_ADD_CLANG_LIB(clangRewriteCore)
endif()
if(CLANG_LIBS OR CLANG_LIBCLANG_LIB)
set(CLANG_FOUND TRUE)
else()
message(STATUS "Could not find any Clang libraries in ${LLVM_LIBRARY_DIRS}")
endif()
if(CLANG_FOUND)
set(CLANG_LIBRARY_DIRS ${LLVM_LIBRARY_DIRS})
set(CLANG_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS})
# check whether llvm-config comes from an install prefix
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root
OUTPUT_VARIABLE _llvmSourceRoot
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled)
if (NOT _llvmIsInstalled)
message(STATUS "Detected that llvm-config comes from a build-tree, adding more include directories for Clang")
list(APPEND CLANG_INCLUDE_DIRS
"${LLVM_INSTALL_PREFIX}/tools/clang/include" # build dir
"${_llvmSourceRoot}/tools/clang/include" # source dir
)
endif()
message(STATUS "Found Clang (LLVM version: ${LLVM_VERSION})")
message(STATUS " Include dirs: ${CLANG_INCLUDE_DIRS}")
message(STATUS " Clang libraries: ${CLANG_LIBS}")
message(STATUS " Libclang C library: ${CLANG_LIBCLANG_LIB}")
else()
if(Clang_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find Clang")
endif()
endif()
# Find the native LLVM includes and libraries
#
# Defines the following variables
# LLVM_INCLUDE_DIRS - where to find llvm include files
# LLVM_LIBRARY_DIRS - where to find llvm libs
# LLVM_CFLAGS - llvm compiler flags
# LLVM_LFLAGS - llvm linker flags
# LLVM_MODULE_LIBS - list of llvm libs for working with modules.
# LLVM_INSTALL_PREFIX - LLVM installation prefix
# LLVM_FOUND - True if llvm found.
# LLVM_VERSION - Version string ("llvm-config --version")
#
# This module reads hints about search locations from variables
# LLVM_ROOT - Preferred LLVM installation prefix (containing bin/, lib/, ...)
#
# Note: One may specify these as environment variables if they are not specified as
# CMake variables or cache entries.
#=============================================================================
# Copyright 2014 Kevin Funk <kfunk@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if (NOT LLVM_ROOT AND DEFINED ENV{LLVM_ROOT})
file(TO_CMAKE_PATH "$ENV{LLVM_ROOT}" LLVM_ROOT)
endif()
# if the user specified LLVM_ROOT, use that and fail otherwise
if (LLVM_ROOT)
find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config HINTS ${LLVM_ROOT}/bin DOC "llvm-config executable" NO_DEFAULT_PATH)
else()
# find llvm-config, prefer the one with a version suffix, e.g. llvm-config-3.5
# note: FreeBSD installs llvm-config as llvm-config35 and so on
# note: on some distributions, only 'llvm-config' is shipped, so let's always try to fallback on that
string(REPLACE "." "" LLVM_FIND_VERSION_CONCAT ${LLVM_FIND_VERSION})
find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config-${LLVM_FIND_VERSION} llvm-config${LLVM_FIND_VERSION_CONCAT} llvm-config DOC "llvm-config executable")
# other distributions don't ship llvm-config, but only some llvm-config-VERSION binary
# try to deduce installed LLVM version by looking up llvm-nm in PATH and *then* find llvm-config-VERSION via that
if (NOT LLVM_CONFIG_EXECUTABLE)
find_program(_llvmNmExecutable llvm-nm)
if (_llvmNmExecutable)
execute_process(COMMAND ${_llvmNmExecutable} --version OUTPUT_VARIABLE _out)
string(REGEX REPLACE ".*LLVM version ([^ \n]+).*" "\\1" _versionString "${_out}")
find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config-${_versionString} DOC "llvm-config executable")
endif()
endif()
endif()
set(LLVM_FOUND FALSE)
if (LLVM_CONFIG_EXECUTABLE)
# verify that we've found the correct version of llvm-config
execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --version
OUTPUT_VARIABLE LLVM_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT LLVM_VERSION)
set(_LLVM_ERROR_MESSAGE "Failed to parse version from llvm-config")
elseif (LLVM_FIND_VERSION VERSION_GREATER LLVM_VERSION)
set(_LLVM_ERROR_MESSAGE "LLVM version too old: ${LLVM_VERSION}")
else()
set(LLVM_FOUND TRUE)
endif()
else()
set(_LLVM_ERROR_MESSAGE "Could NOT find 'llvm-config' executable")
endif()
if (LLVM_FOUND)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --includedir
OUTPUT_VARIABLE LLVM_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir
OUTPUT_VARIABLE LLVM_LIBRARY_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --cppflags
OUTPUT_VARIABLE LLVM_CFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --ldflags
OUTPUT_VARIABLE LLVM_LFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libs core bitreader asmparser analysis
OUTPUT_VARIABLE LLVM_MODULE_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libfiles
OUTPUT_VARIABLE LLVM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE " " ";" LLVM_LIBS ${LLVM_LIBS}) # Make it consistent with --libs
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --system-libs
OUTPUT_VARIABLE LLVM_SYSTEM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --prefix
OUTPUT_VARIABLE LLVM_INSTALL_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# potentially add include dir from binary dir for non-installed LLVM
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root
OUTPUT_VARIABLE _llvmSourceRoot
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled)
if (NOT _llvmIsInstalled)
list(APPEND LLVM_INCLUDE_DIRS "${LLVM_INSTALL_PREFIX}/include")
endif()
endif()
if (LLVM_FIND_REQUIRED AND NOT LLVM_FOUND)
message(FATAL_ERROR "Could not find LLVM: ${_LLVM_ERROR_MESSAGE}")
elseif(_LLVM_ERROR_MESSAGE)
message(STATUS "Could not find LLVM: ${_LLVM_ERROR_MESSAGE}")
endif()
if (LLVM_FOUND)
message(STATUS "Found LLVM (version: ${LLVM_VERSION}): (using ${LLVM_CONFIG_EXECUTABLE})")
message(STATUS " Include dirs: ${LLVM_INCLUDE_DIRS}")
message(STATUS " LLVM libraries: ${LLVM_LIBS}")
message(STATUS " LLVM System libraries: ${LLVM_SYSTEM_LIBS}")
endif()
#!/usr/bin/env python3
import argparse
import os
import sys
import subprocess
def parse_args(args):
parser = argparse.ArgumentParser(description="XACC Quantum-Classical C++ Compiler.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
fromfile_prefix_chars='@')
parser.add_argument(
'file', help='The quantum-classical C++ file to compile.')
parser.add_argument("-a", "--accelerator", type=str,
help="The target quantum accelerator", required=False)
parser.add_argument("-I", '--include', action='append', type=str,
help="Extra include paths to search", required=False)
parser.add_argument("-o", '--output', type=str,
help="Name of output binary", required=False)
parser.add_argument("-v", '--verbose', action='store_true',
help="Print verbose compiler output.", required=False)
parser.add_argument("--keep-tmp-src", action='store_true',
help="Keep qcor generated hidden source file.", required=False)
opts = parser.parse_args(args)
return opts
def main(argv=None):
opts = parse_args(sys.argv[1:])
import time
command = ["@CMAKE_INSTALL_PREFIX@/bin/xacc-driver"]
includes = []
if opts.include:
for include in opts.include:
includes.append('-I'+include)
command += includes
if opts.accelerator:
command += ['--accelerator', opts.accelerator]
command += [opts.file]
if opts.verbose:
command += ['-v']
#print(command)
try:
s = time.time()
result = subprocess.run(command, check=True)
e = time.time()
#print('time: ', (e-s))
except subprocess.CalledProcessError as e:
print(e.output)
print(e.returncode)
return e.returncode
command.clear()
baseIncludes = ['-I', '@CMAKE_INSTALL_PREFIX@/include/xacc',
'-I', '@CMAKE_INSTALL_PREFIX@/include/cppmicroservices4']
baseLibs = ['@CMAKE_INSTALL_PREFIX@/lib/libxacc.so', '@CMAKE_INSTALL_PREFIX@/lib/libCppMicroServices.so']
command = ['@CMAKE_CXX_COMPILER@', '-Wno-attributes', '-O3', '-DNDEBUG', '-rdynamic', '-std=c++11',
'.' + opts.file.replace('.', '_out.'), '-Wl,-rpath,@CMAKE_INSTALL_PREFIX@/lib']
command += includes + baseIncludes + baseLibs
if opts.output:
command += ['-o', opts.output]
#print('Final command', command)
try:
s = time.time()
result = subprocess.run(command, check=True)
e = time.time()
#print('final compile time: ', (e-s))
except subprocess.CalledProcessError as e:
print(e.output)
print(e.returncode)
return e.returncode
if not opts.keep_tmp_src:
os.remove('.'+opts.file.replace('.','_out.'))
return 0
if __name__ == "__main__":
sys.exit(main())
......@@ -2,11 +2,14 @@
# Copyright (c) 2017 UT-Battelle, LLC.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# and Eclipse Distribution License v.10 which accompany this distribution.
# The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
# and the Eclipse Distribution License is available at
# and Eclipse Distribution License v.10 which accompany this distribution.
# The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
# and the Eclipse Distribution License is available at
# https://eclipse.org/org/documents/edl-v10.php
#
# Contributors:
# Alexander J. McCaskey - initial API and implementation
# Alexander J. McCaskey - initial API and implementation
# *******************************************************************************/
if (CLANG_FOUND)
add_subdirectory(compiler)
endif()
\ No newline at end of file
add_subdirectory(clang)
\ No newline at end of file
set(LIBRARY_NAME xacc-ast-plugin)
add_library(${LIBRARY_NAME}
SHARED
FuzzyParsingExternalSemaSource.cpp
KernelVisitor.cpp
XACCASTConsumer.cpp)
target_include_directories(${LIBRARY_NAME}
PUBLIC .
${CMAKE_BINARY_DIR}
${CLANG_INCLUDE_DIRS}
${LLVM_INCLUDE_DIRS})
target_link_libraries(${LIBRARY_NAME}
PUBLIC ${CLANG_LIBS} ${LLVM_LIBS} xacc CppMicroServices)
if(APPLE)
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH "@loader_path")
set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
else()
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN")
set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-shared")
endif()
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
if(XACC_BUILD_TESTS)
add_subdirectory(tests)
endif()
configure_file(xacc-driver.in.cpp
${CMAKE_BINARY_DIR}/tools/compiler/clang/xacc-driver.cpp)
add_executable(xacc-driver ${CMAKE_BINARY_DIR}/tools/compiler/clang/xacc-driver.cpp)
target_link_libraries(xacc-driver PRIVATE xacc-ast-plugin xacc)
install(PROGRAMS ${CMAKE_BINARY_DIR}/tools/compiler/clang/xacc-driver DESTINATION bin)
install(FILES xacc_runtime.hpp DESTINATION include/xacc)
\ No newline at end of file
#include "FuzzyParsingExternalSemaSource.hpp"
#include "IRProvider.hpp"
#include "XACC.hpp"
#include "IRGenerator.hpp"
#include "xacc_service.hpp"
using namespace clang;
namespace xacc {
namespace compiler {
FuzzyParsingExternalSemaSource::FuzzyParsingExternalSemaSource(
ASTContext &context)
: m_Context(context) {
auto irProvider = xacc::getService<xacc::IRProvider>("quantum");
validInstructions = irProvider->getInstructions();
validInstructions.push_back("CX");
auto irgens = xacc::getRegisteredIds<xacc::IRGenerator>();
for (auto &irg : irgens) {
validInstructions.push_back(irg);
}
}
bool FuzzyParsingExternalSemaSource::LookupUnqualified(clang::LookupResult &R,
clang::Scope *S) {
DeclarationName Name = R.getLookupName();
std::string unknownName = Name.getAsString();
// If this is a valid quantum instruction, tell Clang its
// all gonna be ok, we got this...
if (std::find(validInstructions.begin(),
validInstructions.end(), // not template scope
unknownName) != validInstructions.end()) { //} &&
// S->getFlags() != 128 && S->getBlockParent() != nullptr) {
// std::cout << "HELLO FP: " << unknownName << ", " << S->getFlags() <<
// "\n"; S->dump(); S->getBlockParent()->dump();
IdentifierInfo *II = Name.getAsIdentifierInfo();
SourceLocation Loc = R.getNameLoc();
auto fdecl = FunctionDecl::Create(
m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, Name,
m_Context.DependentTy, 0, SC_None);
Stmt *S = new (m_Context) NullStmt(Stmt::EmptyShell());
fdecl->setBody(S);
R.addDecl(fdecl);
return true;
}
return false;
}
} // namespace compiler
} // namespace xacc
\ No newline at end of file
#ifndef TOOLS_COMPILER_FUZZYPARSINGEXTERNALSEMASOURCE_HPP_
#define TOOLS_COMPILER_FUZZYPARSINGEXTERNALSEMASOURCE_HPP_
#include "clang/AST/ASTContext.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Lookup.h"
using namespace clang;
namespace xacc {
namespace compiler {
class FuzzyParsingExternalSemaSource : public ExternalSemaSource {
private:
ASTContext &m_Context;
std::vector<std::string> validInstructions;
public:
FuzzyParsingExternalSemaSource(ASTContext &context);
bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) override;
};
} // namespace compiler
} // namespace xacc
#endif
\ No newline at end of file
#include "KernelVisitor.hpp"
#include "IRGenerator.hpp"
#include "IRProvider.hpp"
#include "XACC.hpp"
#include "xacc_service.hpp"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Tooling/Tooling.h"
#include <memory>
using namespace clang;
using namespace xacc;
namespace xacc {
namespace compiler {
KernelVisitor::KernelVisitor(CompilerInstance &c, Rewriter &rw)
: ci(c), rewriter(rw) {}
bool KernelVisitor::VisitFunctionDecl(FunctionDecl *F) {
if (F->hasAttr<AnnotateAttr>() &&
F->getAttr<AnnotateAttr>()->getAnnotation().str() == "__qpu__") {
F->dump();
CppToXACCIRVisitor visitor(F->getNameAsString());
visitor.TraverseDecl(F);
auto function = visitor.getFunction();
// std::cout << "XACCIR:\n" << function->toString() << "\n";
if (!xacc::optionExists("accelerator")) {
if (xacc::hasAccelerator("tnqvm")) {
xacc::setOption("accelerator", "tnqvm");
} else if (xacc::hasAccelerator("local-ibm")) {
xacc::setOption("accelerator", "local-ibm");
} else {
xacc::error("No Accelerator specified for compilation. Compile with "
"--accelerator and ensure you have the desired Accelerator "
"installed.");
}
}
auto acceleratorName = xacc::getAccelerator()->name();
// Here we need to do Quantum Compilation
// ...
// ...
//
std::stringstream ss;
function->persist(ss);
auto irStr = ss.str();
auto bufferName = F->getParamDecl(0)->getNameAsString();
auto sr = F->getBody()->getSourceRange();
std::string replacement = "{\n";
replacement += bufferName + "->resetBuffer();\n";
replacement += "auto irstr = R\"irstr(" + irStr + ")irstr\";\n";
replacement += "auto function = xacc::loadFromIR(irstr);\n";
if (F->getNumParams() > 1) {
replacement +=
"std::vector<double> params{" + F->getParamDecl(1)->getNameAsString();
for (int i = 2; i < F->getNumParams(); i++) {
replacement += "," + F->getParamDecl(i)->getNameAsString();
}
replacement += "};\n";
replacement += "function = function->operator()(params);\n";
}
replacement += "xacc::getAccelerator(\"" + acceleratorName +
"\")->execute(" + bufferName + ",function);\n";
replacement += "}\n";
rewriter.ReplaceText(sr, replacement);
xacc::appendCompiled(function);
}