Automate pod arg implementation decision (#575)

Contributes to #529

* Decision made on a per-kernel basis
* New pass assigns metadata to kernels
  * passes use that metadata through new utliities to get the right
  ArgKinds
  * currently only decides based on command line options (so NFC)
* Refactored layout validation into new files
* Refactored some global push constant methods
* new enum for how pod args are implemented
  * kGlobalPushConstant will be implemented in the future
* added new metadata to test that required it
* changed arg kind utility to take the arg instead of just the type
* Priorities per-kernel push constants then ubo then ssbo
  * checks for compatibility
* Added new variant of isValidExplicitLayout that checks the whole
struct
diff --git a/lib/PushConstant.cpp b/lib/PushConstant.cpp
index 2426ae3..ed67e93 100644
--- a/lib/PushConstant.cpp
+++ b/lib/PushConstant.cpp
@@ -22,6 +22,8 @@
 #include "llvm/IR/Type.h"
 #include "llvm/Support/ErrorHandling.h"
 
+#include "clspv/Option.h"
+
 #include "Constants.h"
 
 using namespace llvm;
@@ -101,4 +103,16 @@
   return Builder.CreateInBoundsGEP(GV, Indices);
 }
 
+bool UsesGlobalPushConstants(Module &M) {
+  return clspv::Option::NonUniformNDRangeSupported() ||
+         ShouldDeclareGlobalOffset(M);
+}
+
+bool ShouldDeclareGlobalOffset(Module &M) {
+  bool isEnabled = clspv::Option::GlobalOffset();
+  bool isUsed = (M.getFunction("_Z17get_global_offsetj") != nullptr) ||
+                (M.getFunction("_Z13get_global_idj") != nullptr);
+  return isEnabled && isUsed;
+}
+
 } // namespace clspv