diff options
author | Martin Nowack <martin.nowack@gmail.com> | 2016-08-04 15:43:11 +0200 |
---|---|---|
committer | Martin Nowack <martin@se.inf.tu-dresden.de> | 2016-08-10 21:22:06 +0200 |
commit | 95a39e0fe58c7b95588da97b3478eafba9920281 (patch) | |
tree | e473ca52e739805533b11b11820c251d0672bbb8 /lib/Module/RaiseAsm.cpp | |
parent | 66b3470f4d01df50bc77d9f96e3c526e8e4cbf91 (diff) | |
download | klee-95a39e0fe58c7b95588da97b3478eafba9920281.tar.gz |
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.
Diffstat (limited to 'lib/Module/RaiseAsm.cpp')
-rw-r--r-- | lib/Module/RaiseAsm.cpp | 39 |
1 files changed, 34 insertions, 5 deletions
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<CallInst>(I)) { - if (InlineAsm *ia = dyn_cast<InlineAsm>(ci->getCalledValue())) { - (void) ia; - return TLI && TLI->ExpandInlineAsm(ci); + // We can just raise inline assembler using calls + CallInst *ci = dyn_cast<CallInst>(I); + if (!ci) + return false; + + InlineAsm *ia = dyn_cast<InlineAsm>(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) { |