summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2013-05-18 09:20:39 +0000
committerHal Finkel <hfinkel@anl.gov>2013-05-18 09:20:39 +0000
commit2f474f0e8a53145f585cf040968bde09e13c613d (patch)
tree14ad5f9dcde007f4977710bca0b0c7cf853b9724 /llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
parentfd2639f784bb7b5e7907485a4e207b41e3b6523e (diff)
downloadbcm5719-llvm-2f474f0e8a53145f585cf040968bde09e13c613d.tar.gz
bcm5719-llvm-2f474f0e8a53145f585cf040968bde09e13c613d.zip
Check InlineAsm clobbers in PPCCTRLoops
We don't need to reject all inline asm as using the counter register (most does not). Only those that explicitly clobber the counter register need to prevent the transformation. llvm-svn: 182191
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCCTRLoops.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCCTRLoops.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp b/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
index 5d001fc0725..e8760dedea4 100644
--- a/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
+++ b/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
@@ -33,6 +33,7 @@
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
@@ -148,6 +149,20 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) {
for (BasicBlock::iterator J = BB->begin(), JE = BB->end();
J != JE; ++J) {
if (CallInst *CI = dyn_cast<CallInst>(J)) {
+ if (InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledValue())) {
+ // Inline ASM is okay, unless it clobbers the ctr register.
+ InlineAsm::ConstraintInfoVector CIV = IA->ParseConstraints();
+ for (unsigned i = 0, ie = CIV.size(); i < ie; ++i) {
+ InlineAsm::ConstraintInfo &C = CIV[i];
+ if (C.Type != InlineAsm::isInput)
+ for (unsigned j = 0, je = C.Codes.size(); j < je; ++j)
+ if (StringRef(C.Codes[j]).equals_lower("{ctr}"))
+ return true;
+ }
+
+ continue;
+ }
+
if (!TM)
return true;
const TargetLowering *TLI = TM->getTargetLowering();
OpenPOWER on IntegriCloud