From 95a39e0fe58c7b95588da97b3478eafba9920281 Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Thu, 4 Aug 2016 15:43:11 +0200 Subject: Extended support for assembler raising Improved support for assembler handling. Providing additional triple information to raise assembler for supported architectures only. Implemented support for raising full assembly memory fence. Added initial support for memory fences in Executor. --- lib/Module/RaiseAsm.cpp | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'lib/Module/RaiseAsm.cpp') diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp index 12e5479b..7c0e6ccf 100644 --- a/lib/Module/RaiseAsm.cpp +++ b/lib/Module/RaiseAsm.cpp @@ -9,12 +9,16 @@ #include "Passes.h" #include "klee/Config/Version.h" +#include "klee/Internal/Support/ErrorHandling.h" #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Instructions.h" #else #include "llvm/InlineAsm.h" #include "llvm/LLVMContext.h" +#include "llvm/Support/IRBuilder.h" #endif #include "llvm/Support/raw_ostream.h" @@ -46,10 +50,32 @@ Function *RaiseAsmPass::getIntrinsic(llvm::Module &M, // FIXME: This should just be implemented as a patch to // X86TargetAsmInfo.cpp, then everyone will benefit. bool RaiseAsmPass::runOnInstruction(Module &M, Instruction *I) { - if (CallInst *ci = dyn_cast(I)) { - if (InlineAsm *ia = dyn_cast(ci->getCalledValue())) { - (void) ia; - return TLI && TLI->ExpandInlineAsm(ci); + // We can just raise inline assembler using calls + CallInst *ci = dyn_cast(I); + if (!ci) + return false; + + InlineAsm *ia = dyn_cast(ci->getCalledValue()); + if (!ia) + return false; + + // Try to use existing infrastructure + if (!TLI) + return false; + + if (TLI->ExpandInlineAsm(ci)) + return true; + + if (triple.getArch() == llvm::Triple::x86_64 && + triple.getOS() == llvm::Triple::Linux) { + + if (ia->getAsmString() == "" && ia->hasSideEffects()) { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) + IRBuilder<> Builder(I); + Builder.CreateFence(llvm::SequentiallyConsistent); +#endif + I->eraseFromParent(); + return true; } } @@ -66,9 +92,10 @@ bool RaiseAsmPass::runOnModule(Module &M) { std::string HostTriple = llvm::sys::getHostTriple(); #endif const Target *NativeTarget = TargetRegistry::lookupTarget(HostTriple, Err); + TargetMachine * TM = 0; if (NativeTarget == 0) { - llvm::errs() << "Warning: unable to select native target: " << Err << "\n"; + klee_warning("Warning: unable to select native target: %s", Err.c_str()); TLI = 0; } else { #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 1) @@ -80,6 +107,8 @@ bool RaiseAsmPass::runOnModule(Module &M) { TM = NativeTarget->createTargetMachine(HostTriple, ""); #endif TLI = TM->getTargetLowering(); + + triple = llvm::Triple(HostTriple); } for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) { -- cgit 1.4.1