set(sources llvm_wrapper.cpp
orc_compile_stack.cpp)
add_library(vulkan_cpu_llvm_wrapper STATIC ${sources})
-if(0)
-llvm_map_components_to_libnames(llvm_libraries core native analysis orcjit mcjit nativecodegen)
+if(1)
+llvm_map_components_to_libnames(llvm_libraries core native analysis orcjit mcjit nativecodegen ipo scalaropts vectorize)
else()
set(llvm_libraries LLVM)
endif()
#include <llvm-c/TargetMachine.h>
#include <llvm-c/OrcBindings.h>
#include <llvm-c/Analysis.h>
+#include <llvm-c/Transforms/IPO.h>
+#include <llvm-c/Transforms/Scalar.h>
+#include <llvm-c/Transforms/Vectorize.h>
#include <memory>
#include <type_traits>
#include <utility>
::LLVMValueRef rhs,
const char *result_name)
{
+ if(::LLVMGetValueKind(rhs) == ::LLVMConstantIntValueKind)
+ {
+ unsigned long long value = ::LLVMConstIntGetZExtValue(rhs);
+ if(value == 0)
+ return ::LLVMGetUndef(::LLVMTypeOf(rhs));
+ if((value & (value - 1)) == 0)
+ return ::LLVMBuildAnd(builder, lhs, ::LLVMConstInt(::LLVMTypeOf(rhs), value - 1, false), result_name);
+ }
auto srem_result = ::LLVMBuildSRem(builder, lhs, rhs, "");
auto zero_constant = ::LLVMConstInt(::LLVMTypeOf(lhs), 0, false);
auto different_signs = ::LLVMBuildICmp(
}
};
+struct Pass_manager_deleter
+{
+ void operator()(::LLVMPassManagerRef v) const noexcept
+ {
+ ::LLVMDisposePassManager(v);
+ }
+};
+
+struct Pass_manager : public Wrapper<::LLVMPassManagerRef, Pass_manager_deleter>
+{
+ using Wrapper::Wrapper;
+ static Pass_manager create_module_pass_manager()
+ {
+ return Pass_manager(::LLVMCreatePassManager());
+ }
+ static Pass_manager create_function_pass_manager(::LLVMModuleRef module)
+ {
+ return Pass_manager(::LLVMCreateFunctionPassManagerForModule(module));
+ }
+};
+
inline ::LLVMTypeRef get_scalar_or_vector_element_type(::LLVMTypeRef type)
{
if(::LLVMGetTypeKind(type) == ::LLVMTypeKind::LLVMVectorTypeKind)
case ::LLVMCodeGenLevelAggressive:
{
#warning finish implementing module optimizations
+ {
+ auto manager = llvm_wrapper::Pass_manager::create_function_pass_manager(module.get());
+ ::LLVMAddPromoteMemoryToRegisterPass(manager.get());
+ ::LLVMAddScalarReplAggregatesPass(manager.get());
+ ::LLVMAddScalarizerPass(manager.get());
+ ::LLVMAddEarlyCSEMemSSAPass(manager.get());
+ ::LLVMAddSCCPPass(manager.get());
+ ::LLVMAddAggressiveDCEPass(manager.get());
+ ::LLVMAddLICMPass(manager.get());
+ ::LLVMAddCFGSimplificationPass(manager.get());
+ ::LLVMAddReassociatePass(manager.get());
+ ::LLVMAddInstructionCombiningPass(manager.get());
+ ::LLVMAddNewGVNPass(manager.get());
+ ::LLVMAddCorrelatedValuePropagationPass(manager.get());
+ ::LLVMInitializeFunctionPassManager(manager.get());
+ for(auto fn = ::LLVMGetFirstFunction(module.get()); fn; fn = ::LLVMGetNextFunction(fn))
+ ::LLVMRunFunctionPassManager(manager.get(), fn);
+ ::LLVMFinalizeFunctionPassManager(manager.get());
+ }
+ {
+ auto manager = llvm_wrapper::Pass_manager::create_module_pass_manager();
+ ::LLVMAddIPSCCPPass(manager.get());
+ ::LLVMAddFunctionInliningPass(manager.get());
+ ::LLVMAddDeadArgEliminationPass(manager.get());
+ ::LLVMAddGlobalDCEPass(manager.get());
+ ::LLVMRunPassManager(manager.get(), module.get());
+ }
+ {
+ auto manager = llvm_wrapper::Pass_manager::create_function_pass_manager(module.get());
+ ::LLVMAddCFGSimplificationPass(manager.get());
+ ::LLVMAddPromoteMemoryToRegisterPass(manager.get());
+ ::LLVMAddScalarReplAggregatesPass(manager.get());
+ ::LLVMAddReassociatePass(manager.get());
+ ::LLVMAddInstructionCombiningPass(manager.get());
+ ::LLVMAddLoopUnrollPass(manager.get());
+ ::LLVMAddSLPVectorizePass(manager.get());
+ ::LLVMAddAggressiveDCEPass(manager.get());
+ ::LLVMInitializeFunctionPassManager(manager.get());
+ for(auto fn = ::LLVMGetFirstFunction(module.get()); fn; fn = ::LLVMGetNextFunction(fn))
+ ::LLVMRunFunctionPassManager(manager.get(), fn);
+ ::LLVMFinalizeFunctionPassManager(manager.get());
+ }
std::cerr << "optimized module:" << std::endl;
::LLVMDumpModule(module.get());
break;
void Spirv_to_llvm::handle_instruction_op_s_rem(Op_s_rem instruction,
std::size_t instruction_start_index)
{
-#warning finish
- throw Parser_error(instruction_start_index,
- instruction_start_index,
- "instruction not implemented: "
- + std::string(get_enumerant_name(instruction.get_operation())));
+ switch(stage)
+ {
+ case Stage::calculate_types:
+ break;
+ case Stage::generate_code:
+ {
+ auto &state = get_id_state(instruction.result);
+ if(!state.decorations.empty())
+ throw Parser_error(instruction_start_index,
+ instruction_start_index,
+ "decorations on instruction not implemented: "
+ + std::string(get_enumerant_name(instruction.get_operation())));
+ auto result_type = get_type(instruction.result_type, instruction_start_index);
+ state.value = Value(::LLVMBuildSRem(builder.get(),
+ get_id_state(instruction.operand_1).value.value().value,
+ get_id_state(instruction.operand_2).value.value().value,
+ get_name(instruction.result).c_str()),
+ result_type);
+ break;
+ }
+ }
}
void Spirv_to_llvm::handle_instruction_op_s_mod(Op_s_mod instruction,