Factor out RSObjectRefCount for destructor work.
Change-Id: Ibdacc9e9f15401680bc54747664e187a05f62e25
diff --git a/Android.mk b/Android.mk
index 17c289b..8094b50 100644
--- a/Android.mk
+++ b/Android.mk
@@ -188,6 +188,7 @@
slang_rs_export_element.cpp \
slang_rs_export_var.cpp \
slang_rs_export_func.cpp \
+ slang_rs_object_ref_count.cpp \
slang_rs_reflection.cpp \
slang_rs_reflect_utils.cpp \
slang_rs_metadata_spec_encoder.cpp
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp
index 3088d3f..f59804c 100644
--- a/slang_rs_backend.cpp
+++ b/slang_rs_backend.cpp
@@ -16,7 +16,6 @@
#include "slang_rs_backend.h"
-#include <stack>
#include <vector>
#include <string>
@@ -32,12 +31,6 @@
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/StringExtras.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/OperationKinds.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtVisitor.h"
-
#include "slang_rs.h"
#include "slang_rs_context.h"
#include "slang_rs_metadata.h"
@@ -71,226 +64,12 @@
return;
}
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
- class RSObjectRefCounting : public clang::StmtVisitor<RSObjectRefCounting> {
- private:
- class Scope {
- private:
- clang::CompoundStmt *mCS; // Associated compound statement ({ ... })
- std::list<clang::Decl*> mRSO; // Declared RS object in this scope
-
- public:
- Scope(clang::CompoundStmt *CS) : mCS(CS) {
- return;
- }
-
- inline void addRSObject(clang::Decl* D) { mRSO.push_back(D); }
- };
- std::stack<Scope*> mScopeStack;
-
- inline Scope *getCurrentScope() { return mScopeStack.top(); }
-
- // Return false if the type of variable declared in VD is not an RS object
- // type.
- static bool InitializeRSObject(clang::VarDecl *VD);
- // Return an zero-initializer expr of the type DT. This processes both
- // RS matrix type and RS object type.
- static clang::Expr *CreateZeroInitializerForRSSpecificType(
- RSExportPrimitiveType::DataType DT,
- clang::ASTContext &C,
- const clang::SourceLocation &Loc);
-
- public:
- void VisitChildren(clang::Stmt *S) {
- for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
- I != E;
- I++)
- if (clang::Stmt *Child = *I)
- Visit(Child);
- }
- void VisitStmt(clang::Stmt *S) { VisitChildren(S); }
-
- void VisitDeclStmt(clang::DeclStmt *DS);
- void VisitCompoundStmt(clang::CompoundStmt *CS);
- void VisitBinAssign(clang::BinaryOperator *AS);
-
- // We believe that RS objects never are involved in CompoundAssignOperator.
- // I.e., rs_allocation foo; foo += bar;
- };
-}
-
-bool RSObjectRefCounting::InitializeRSObject(clang::VarDecl *VD) {
- const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
- RSExportPrimitiveType::DataType DT =
- RSExportPrimitiveType::GetRSSpecificType(T);
-
- if (DT == RSExportPrimitiveType::DataTypeUnknown)
- return false;
-
- if (VD->hasInit()) {
- // TODO: Update the reference count of RS object in initializer.
- // This can potentially be done as part of the assignment pass.
- } else {
- clang::Expr *ZeroInitializer =
- CreateZeroInitializerForRSSpecificType(DT,
- VD->getASTContext(),
- VD->getLocation());
-
- if (ZeroInitializer) {
- ZeroInitializer->setType(T->getCanonicalTypeInternal());
- VD->setInit(ZeroInitializer);
- }
- }
-
- return RSExportPrimitiveType::IsRSObjectType(DT);
-}
-
-clang::Expr *RSObjectRefCounting::CreateZeroInitializerForRSSpecificType(
- RSExportPrimitiveType::DataType DT,
- clang::ASTContext &C,
- const clang::SourceLocation &Loc) {
- clang::Expr *Res = NULL;
- switch (DT) {
- case RSExportPrimitiveType::DataTypeRSElement:
- case RSExportPrimitiveType::DataTypeRSType:
- case RSExportPrimitiveType::DataTypeRSAllocation:
- case RSExportPrimitiveType::DataTypeRSSampler:
- case RSExportPrimitiveType::DataTypeRSScript:
- case RSExportPrimitiveType::DataTypeRSMesh:
- case RSExportPrimitiveType::DataTypeRSProgramFragment:
- case RSExportPrimitiveType::DataTypeRSProgramVertex:
- case RSExportPrimitiveType::DataTypeRSProgramRaster:
- case RSExportPrimitiveType::DataTypeRSProgramStore:
- case RSExportPrimitiveType::DataTypeRSFont: {
- // (ImplicitCastExpr 'nullptr_t'
- // (IntegerLiteral 0)))
- llvm::APInt Zero(C.getTypeSize(C.IntTy), 0);
- clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc);
- clang::Expr *CastToNull =
- clang::ImplicitCastExpr::Create(C,
- C.NullPtrTy,
- clang::CK_IntegralToPointer,
- Int0,
- NULL,
- clang::VK_RValue);
-
- Res = new (C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc);
- break;
- }
- case RSExportPrimitiveType::DataTypeRSMatrix2x2:
- case RSExportPrimitiveType::DataTypeRSMatrix3x3:
- case RSExportPrimitiveType::DataTypeRSMatrix4x4: {
- // RS matrix is not completely an RS object. They hold data by themselves.
- // (InitListExpr rs_matrix2x2
- // (InitListExpr float[4]
- // (FloatingLiteral 0)
- // (FloatingLiteral 0)
- // (FloatingLiteral 0)
- // (FloatingLiteral 0)))
- clang::QualType FloatTy = C.FloatTy;
- // Constructor sets value to 0.0f by default
- llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy));
- clang::FloatingLiteral *Float0Val =
- clang::FloatingLiteral::Create(C,
- Val,
- /* isExact = */true,
- FloatTy,
- Loc);
-
- unsigned N = 0;
- if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2)
- N = 2;
- else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3)
- N = 3;
- else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4)
- N = 4;
-
- // Directly allocate 16 elements instead of dynamically allocate N*N
- clang::Expr *InitVals[16];
- for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++)
- InitVals[i] = Float0Val;
- clang::Expr *InitExpr =
- new (C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc);
- InitExpr->setType(C.getConstantArrayType(FloatTy,
- llvm::APInt(32, 4),
- clang::ArrayType::Normal,
- /* EltTypeQuals = */0));
-
- Res = new (C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc);
- break;
- }
- case RSExportPrimitiveType::DataTypeUnknown:
- case RSExportPrimitiveType::DataTypeFloat16:
- case RSExportPrimitiveType::DataTypeFloat32:
- case RSExportPrimitiveType::DataTypeFloat64:
- case RSExportPrimitiveType::DataTypeSigned8:
- case RSExportPrimitiveType::DataTypeSigned16:
- case RSExportPrimitiveType::DataTypeSigned32:
- case RSExportPrimitiveType::DataTypeSigned64:
- case RSExportPrimitiveType::DataTypeUnsigned8:
- case RSExportPrimitiveType::DataTypeUnsigned16:
- case RSExportPrimitiveType::DataTypeUnsigned32:
- case RSExportPrimitiveType::DataTypeUnsigned64:
- case RSExportPrimitiveType::DataTypeBoolean:
- case RSExportPrimitiveType::DataTypeUnsigned565:
- case RSExportPrimitiveType::DataTypeUnsigned5551:
- case RSExportPrimitiveType::DataTypeUnsigned4444:
- case RSExportPrimitiveType::DataTypeMax: {
- assert(false && "Not RS object type!");
- }
- // No default case will enable compiler detecting the missing cases
- }
-
- return Res;
-}
-
-void RSObjectRefCounting::VisitDeclStmt(clang::DeclStmt *DS) {
- for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
- I != E;
- I++) {
- clang::Decl *D = *I;
- if (D->getKind() == clang::Decl::Var) {
- clang::VarDecl *VD = static_cast<clang::VarDecl*>(D);
- if (InitializeRSObject(VD))
- getCurrentScope()->addRSObject(VD);
- }
- }
- return;
-}
-
-void RSObjectRefCounting::VisitCompoundStmt(clang::CompoundStmt *CS) {
- if (!CS->body_empty()) {
- // Push a new scope
- Scope *S = new Scope(CS);
- mScopeStack.push(S);
-
- VisitChildren(CS);
-
- // Destroy the scope
- // TODO: Update reference count of the RS object refenced by the
- // getCurrentScope().
- assert((getCurrentScope() == S) && "Corrupted scope stack!");
- mScopeStack.pop();
- delete S;
- }
- return;
-}
-
-void RSObjectRefCounting::VisitBinAssign(clang::BinaryOperator *AS) {
- // TODO: Update reference count
- return;
-}
-
// 1) Add zero initialization of local RS object types
void RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
if (FD &&
FD->hasBody() &&
!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
- RSObjectRefCounting RSObjectRefCounter;
- RSObjectRefCounter.Visit(FD->getBody());
+ mRefCount.Visit(FD->getBody());
}
return;
}
diff --git a/slang_rs_backend.h b/slang_rs_backend.h
index 88ec098..26210b7 100644
--- a/slang_rs_backend.h
+++ b/slang_rs_backend.h
@@ -19,6 +19,7 @@
#include "slang_backend.h"
#include "slang_pragma_recorder.h"
+#include "slang_rs_object_ref_count.h"
namespace llvm {
class NamedMDNode;
@@ -52,6 +53,8 @@
llvm::NamedMDNode *mExportTypeMetadata;
llvm::NamedMDNode *mExportElementMetadata;
+ RSObjectRefCount mRefCount;
+
void AnnotateFunction(clang::FunctionDecl *FD);
protected:
diff --git a/slang_rs_object_ref_count.cpp b/slang_rs_object_ref_count.cpp
new file mode 100644
index 0000000..e2e9117
--- /dev/null
+++ b/slang_rs_object_ref_count.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "slang_rs_object_ref_count.h"
+
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+
+#include "slang_rs.h"
+#include "slang_rs_export_type.h"
+
+using namespace slang;
+
+bool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD) {
+ const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
+ RSExportPrimitiveType::DataType DT =
+ RSExportPrimitiveType::GetRSSpecificType(T);
+
+ if (DT == RSExportPrimitiveType::DataTypeUnknown)
+ return false;
+
+ if (VD->hasInit()) {
+ // TODO: Update the reference count of RS object in initializer.
+ // This can potentially be done as part of the assignment pass.
+ } else {
+ clang::Expr *ZeroInitializer =
+ CreateZeroInitializerForRSSpecificType(DT,
+ VD->getASTContext(),
+ VD->getLocation());
+
+ if (ZeroInitializer) {
+ ZeroInitializer->setType(T->getCanonicalTypeInternal());
+ VD->setInit(ZeroInitializer);
+ }
+ }
+
+ return RSExportPrimitiveType::IsRSObjectType(DT);
+}
+
+clang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType(
+ RSExportPrimitiveType::DataType DT,
+ clang::ASTContext &C,
+ const clang::SourceLocation &Loc) {
+ clang::Expr *Res = NULL;
+ switch (DT) {
+ case RSExportPrimitiveType::DataTypeRSElement:
+ case RSExportPrimitiveType::DataTypeRSType:
+ case RSExportPrimitiveType::DataTypeRSAllocation:
+ case RSExportPrimitiveType::DataTypeRSSampler:
+ case RSExportPrimitiveType::DataTypeRSScript:
+ case RSExportPrimitiveType::DataTypeRSMesh:
+ case RSExportPrimitiveType::DataTypeRSProgramFragment:
+ case RSExportPrimitiveType::DataTypeRSProgramVertex:
+ case RSExportPrimitiveType::DataTypeRSProgramRaster:
+ case RSExportPrimitiveType::DataTypeRSProgramStore:
+ case RSExportPrimitiveType::DataTypeRSFont: {
+ // (ImplicitCastExpr 'nullptr_t'
+ // (IntegerLiteral 0)))
+ llvm::APInt Zero(C.getTypeSize(C.IntTy), 0);
+ clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc);
+ clang::Expr *CastToNull =
+ clang::ImplicitCastExpr::Create(C,
+ C.NullPtrTy,
+ clang::CK_IntegralToPointer,
+ Int0,
+ NULL,
+ clang::VK_RValue);
+
+ Res = new (C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc);
+ break;
+ }
+ case RSExportPrimitiveType::DataTypeRSMatrix2x2:
+ case RSExportPrimitiveType::DataTypeRSMatrix3x3:
+ case RSExportPrimitiveType::DataTypeRSMatrix4x4: {
+ // RS matrix is not completely an RS object. They hold data by themselves.
+ // (InitListExpr rs_matrix2x2
+ // (InitListExpr float[4]
+ // (FloatingLiteral 0)
+ // (FloatingLiteral 0)
+ // (FloatingLiteral 0)
+ // (FloatingLiteral 0)))
+ clang::QualType FloatTy = C.FloatTy;
+ // Constructor sets value to 0.0f by default
+ llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy));
+ clang::FloatingLiteral *Float0Val =
+ clang::FloatingLiteral::Create(C,
+ Val,
+ /* isExact = */true,
+ FloatTy,
+ Loc);
+
+ unsigned N = 0;
+ if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2)
+ N = 2;
+ else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3)
+ N = 3;
+ else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4)
+ N = 4;
+
+ // Directly allocate 16 elements instead of dynamically allocate N*N
+ clang::Expr *InitVals[16];
+ for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++)
+ InitVals[i] = Float0Val;
+ clang::Expr *InitExpr =
+ new (C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc);
+ InitExpr->setType(C.getConstantArrayType(FloatTy,
+ llvm::APInt(32, 4),
+ clang::ArrayType::Normal,
+ /* EltTypeQuals = */0));
+
+ Res = new (C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc);
+ break;
+ }
+ case RSExportPrimitiveType::DataTypeUnknown:
+ case RSExportPrimitiveType::DataTypeFloat16:
+ case RSExportPrimitiveType::DataTypeFloat32:
+ case RSExportPrimitiveType::DataTypeFloat64:
+ case RSExportPrimitiveType::DataTypeSigned8:
+ case RSExportPrimitiveType::DataTypeSigned16:
+ case RSExportPrimitiveType::DataTypeSigned32:
+ case RSExportPrimitiveType::DataTypeSigned64:
+ case RSExportPrimitiveType::DataTypeUnsigned8:
+ case RSExportPrimitiveType::DataTypeUnsigned16:
+ case RSExportPrimitiveType::DataTypeUnsigned32:
+ case RSExportPrimitiveType::DataTypeUnsigned64:
+ case RSExportPrimitiveType::DataTypeBoolean:
+ case RSExportPrimitiveType::DataTypeUnsigned565:
+ case RSExportPrimitiveType::DataTypeUnsigned5551:
+ case RSExportPrimitiveType::DataTypeUnsigned4444:
+ case RSExportPrimitiveType::DataTypeMax: {
+ assert(false && "Not RS object type!");
+ }
+ // No default case will enable compiler detecting the missing cases
+ }
+
+ return Res;
+}
+
+void RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) {
+ for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
+ I != E;
+ I++) {
+ clang::Decl *D = *I;
+ if (D->getKind() == clang::Decl::Var) {
+ clang::VarDecl *VD = static_cast<clang::VarDecl*>(D);
+ if (InitializeRSObject(VD))
+ getCurrentScope()->addRSObject(VD);
+ }
+ }
+ return;
+}
+
+void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) {
+ if (!CS->body_empty()) {
+ // Push a new scope
+ Scope *S = new Scope(CS);
+ mScopeStack.push(S);
+
+ VisitStmt(CS);
+
+ // Destroy the scope
+ // TODO: Update reference count of the RS object refenced by
+ // getCurrentScope().
+ assert((getCurrentScope() == S) && "Corrupted scope stack!");
+ mScopeStack.pop();
+ delete S;
+ }
+ return;
+}
+
+void RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) {
+ // TODO: Update reference count
+ return;
+}
+
+void RSObjectRefCount::VisitStmt(clang::Stmt *S) {
+ for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
+ I != E;
+ I++) {
+ if (clang::Stmt *Child = *I) {
+ Visit(Child);
+ }
+ }
+ return;
+}
+
diff --git a/slang_rs_object_ref_count.h b/slang_rs_object_ref_count.h
new file mode 100644
index 0000000..abceb6b
--- /dev/null
+++ b/slang_rs_object_ref_count.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stack>
+
+#include "clang/AST/StmtVisitor.h"
+
+#include "slang_rs_export_type.h"
+
+using namespace slang;
+
+namespace clang {
+ class Expr;
+}
+
+class RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> {
+ private:
+ class Scope {
+ private:
+ clang::CompoundStmt *mCS; // Associated compound statement ({ ... })
+ std::list<clang::Decl*> mRSO; // Declared RS objects in this scope
+
+ public:
+ Scope(clang::CompoundStmt *CS) : mCS(CS) {
+ return;
+ }
+
+ inline void addRSObject(clang::Decl* D) {
+ mRSO.push_back(D);
+ return;
+ }
+ };
+
+ std::stack<Scope*> mScopeStack;
+
+ inline Scope *getCurrentScope() {
+ return mScopeStack.top();
+ }
+
+ // Return false if the type of variable declared in VD is not an RS object
+ // type.
+ static bool InitializeRSObject(clang::VarDecl *VD);
+
+ // Return a zero-initializer expr of the type DT. This processes both
+ // RS matrix type and RS object type.
+ static clang::Expr *CreateZeroInitializerForRSSpecificType(
+ RSExportPrimitiveType::DataType DT,
+ clang::ASTContext &C,
+ const clang::SourceLocation &Loc);
+
+ public:
+ void VisitStmt(clang::Stmt *S);
+ void VisitDeclStmt(clang::DeclStmt *DS);
+ void VisitCompoundStmt(clang::CompoundStmt *CS);
+ void VisitBinAssign(clang::BinaryOperator *AS);
+
+ // We believe that RS objects are never involved in CompoundAssignOperator.
+ // I.e., rs_allocation foo; foo += bar;
+};
+