summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRInterpreter.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2016-02-12 21:16:58 +0000
committerSean Callanan <scallanan@apple.com>2016-02-12 21:16:58 +0000
commit8c62daf250020c76a78c54c2efc321d61c84f411 (patch)
treec5a46e269b9de4e8aec37ad7cd64b8c0f3fc17d4 /lldb/source/Expression/IRInterpreter.cpp
parentb281480203663a1add8248f400947b8d23db9509 (diff)
downloadbcm5719-llvm-8c62daf250020c76a78c54c2efc321d61c84f411.tar.gz
bcm5719-llvm-8c62daf250020c76a78c54c2efc321d61c84f411.zip
IRInterpreter now recognizes expressions with constants it doesn't handle.
If an instruction has a constant that IRInterpreter doesn't know how to deal with (say, an array constant, because we can't materialize it to APInt) then we used to ignore that and only fail during expression execution. This is annoying because if IRInterpreter had just returned false from CanInterpret(), the JIT would have been used. Now the IRInterpreter checks constants as part of CanInterpret(), so this should hopefully no longer be an issue. llvm-svn: 260735
Diffstat (limited to 'lldb/source/Expression/IRInterpreter.cpp')
-rw-r--r--lldb/source/Expression/IRInterpreter.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index 29c6742fa87..2b9bb7c53c7 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -465,6 +465,45 @@ static const char *memory_read_error = "Interpreter couldn't read
static const char *infinite_loop_error = "Interpreter ran for too many cycles";
//static const char *bad_result_error = "Result of expression is in bad memory";
+static bool
+CanResolveConstant (llvm::Constant *constant)
+{
+ switch (constant->getValueID())
+ {
+ default:
+ return false;
+ case Value::ConstantIntVal:
+ case Value::ConstantFPVal:
+ return true;
+ case Value::ConstantExprVal:
+ if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
+ {
+ switch (constant_expr->getOpcode())
+ {
+ default:
+ return false;
+ case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
+ case Instruction::BitCast:
+ return CanResolveConstant(constant_expr->getOperand(0));
+ case Instruction::GetElementPtr:
+ {
+ ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
+ Constant *base = dyn_cast<Constant>(*op_cursor);
+ if (!base)
+ return false;
+
+ return CanResolveConstant(base);
+ }
+ }
+ } else {
+ return false;
+ }
+ case Value::ConstantPointerNullVal:
+ return true;
+ }
+}
+
bool
IRInterpreter::CanInterpret (llvm::Module &module,
llvm::Function &function,
@@ -611,6 +650,17 @@ IRInterpreter::CanInterpret (llvm::Module &module,
return false;
}
}
+
+ if (Constant *constant = llvm::dyn_cast<Constant>(operand))
+ {
+ if (!CanResolveConstant(constant))
+ {
+ if (log)
+ log->Printf("Unsupported constant: %s", PrintValue(constant).c_str());
+ error.SetErrorString(unsupported_operand_error);
+ return false;
+ }
+ }
}
}
OpenPOWER on IntegriCloud