Fix cases where RSInvariant pass might miss marking some loads as invariant.
llvm-rs-cc and bcc can add numeric suffixes to structure type names; we need
to tolerate this when looking for the context structure by name.
Bug: 21815112
Change-Id: If5ef169245f8d43affdc43abb2298c7015568dd0
diff --git a/include/bcc/Renderscript/RSUtils.h b/include/bcc/Renderscript/RSUtils.h
index fa1fb1a..edc7fdf 100644
--- a/include/bcc/Renderscript/RSUtils.h
+++ b/include/bcc/Renderscript/RSUtils.h
@@ -20,9 +20,23 @@
#include "rsDefines.h"
#include <llvm/IR/Type.h>
+#include <llvm/IR/DerivedTypes.h>
namespace {
+static inline llvm::StringRef getUnsuffixedStructName(const llvm::StructType *T) {
+ // Get just the object type name with no suffix.
+ size_t LastDot = T->getName().rfind('.');
+ if (LastDot == strlen("struct")) {
+ // If we get back to just the "struct" part, we know that we had a
+ // raw typename (i.e. struct.rs_element with no ".[0-9]+" suffix on it.
+ // In that case, we will want to create our slice such that it contains
+ // the entire name.
+ LastDot = T->getName().size();
+ }
+ return T->getStructName().slice(0, LastDot);
+}
+
const char kAllocationTypeName[] = "struct.rs_allocation";
const char kElementTypeName[] = "struct.rs_element";
const char kSamplerTypeName[] = "struct.rs_sampler";
@@ -36,16 +50,7 @@
// handling would be necessary.
static inline enum RsDataType getRsDataTypeForType(const llvm::Type *T) {
if (T->isStructTy()) {
- // Get just the object type name with no suffix.
- size_t LastDot = T->getStructName().rfind('.');
- if (LastDot == strlen("struct")) {
- // If we get back to just the "struct" part, we know that we had a
- // raw typename (i.e. struct.rs_element with no ".[0-9]+" suffix on it.
- // In that case, we will want to create our slice such that it contains
- // the entire name.
- LastDot = T->getStructName().size();
- }
- const llvm::StringRef StructName = T->getStructName().slice(0, LastDot);
+ const llvm::StringRef StructName = getUnsuffixedStructName(llvm::dyn_cast<const llvm::StructType>(T));
if (StructName.equals(kAllocationTypeName)) {
return RS_TYPE_ALLOCATION;
} else if (StructName.equals(kElementTypeName)) {
diff --git a/lib/Renderscript/RSInvariant.cpp b/lib/Renderscript/RSInvariant.cpp
index a741a22..eb11d7e 100644
--- a/lib/Renderscript/RSInvariant.cpp
+++ b/lib/Renderscript/RSInvariant.cpp
@@ -15,6 +15,7 @@
*/
#include "bcc/Renderscript/RSTransforms.h"
+#include "bcc/Renderscript/RSUtils.h"
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
@@ -80,7 +81,7 @@
const llvm::Type *ArgPtrDomainType = ArgType->getPointerElementType();
if (auto ArgPtrDomainStructType = llvm::dyn_cast<llvm::StructType>(ArgPtrDomainType)) {
if (!ArgPtrDomainStructType->isLiteral()) {
- const llvm::StringRef StructName = ArgPtrDomainStructType->getName();
+ const llvm::StringRef StructName = getUnsuffixedStructName(ArgPtrDomainStructType);
if (StructName.equals("struct.rs_kernel_context_t") || StructName.equals("RsExpandKernelDriverInfoPfx")) {
Changed |= markInvariantUserLoads(&Arg);
}