[llvm] [llvm][ARM]Add widen strings pass (PR #107120)

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 16 08:55:50 PDT 2024


================
@@ -2029,6 +2031,145 @@ OptimizeFunctions(Module &M,
   return Changed;
 }
 
+static bool IsCharArray(Type *t) {
+  const unsigned int CHAR_BIT_SIZE = 8;
+  return t && t->isArrayTy() && t->getArrayElementType()->isIntegerTy() &&
+         t->getArrayElementType()->getIntegerBitWidth() == CHAR_BIT_SIZE;
+}
+
+static bool
+tryWidenGlobalStrings(Function &F,
+                      function_ref<TargetTransformInfo &(Function &)> GetTTI) {
+  bool changed = false;
+
+  for (Function::iterator b = F.begin(); b != F.end(); ++b) {
+    for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) {
+      CallInst *CI = dyn_cast<CallInst>(i);
+      if (!CI) {
+        continue;
+      }
+
+      TargetTransformInfo &TTI = GetTTI(F);
+
+      Function *CallMemcpy = CI->getCalledFunction();
+      // find out if the current call instruction is a call to llvm memcpy
+      // intrinsics
+      if (CallMemcpy == NULL || !CallMemcpy->isIntrinsic() ||
+          CallMemcpy->getIntrinsicID() != Intrinsic::memcpy) {
+        continue;
+      }
+
+      auto *Alloca = dyn_cast<AllocaInst>(CI->getArgOperand(0));
+      auto *SourceVar = dyn_cast<GlobalVariable>(CI->getArgOperand(1));
+      auto *BytesToCopy = dyn_cast<ConstantInt>(CI->getArgOperand(2));
+      auto *IsVolatile = dyn_cast<ConstantInt>(CI->getArgOperand(3));
+
+      if (!BytesToCopy) {
+        continue;
+      }
+
+      uint64_t NumBytesToCopy = BytesToCopy->getZExtValue();
+
+      if (!Alloca) {
+        continue;
+      }
+
+      // Source isn't a global constant variable
+      if (!SourceVar) {
+        continue;
+      }
+
+      if (!IsVolatile || IsVolatile->isOne()) {
+        continue;
+      }
+
+      if (NumBytesToCopy % 4 == 0) {
+        continue;
+      }
+
+      if (!SourceVar->hasInitializer() || !SourceVar->isConstant() ||
+          !SourceVar->hasLocalLinkage() || !SourceVar->hasGlobalUnnamedAddr()) {
+        continue;
+      }
+
+      ConstantDataArray *SourceDataArray =
+          dyn_cast<ConstantDataArray>(SourceVar->getInitializer());
+      if (!SourceDataArray || !IsCharArray(SourceDataArray->getType())) {
+        continue;
+      }
+
+      if (!Alloca->isStaticAlloca()) {
+        continue;
+      }
+
+      // Make sure destination is definitley a char array.
+      if (!IsCharArray(Alloca->getAllocatedType())) {
+        continue;
+      }
+
+      uint64_t DZSize = Alloca->getAllocatedType()->getArrayNumElements();
+      uint64_t SZSize = SourceDataArray->getType()->getNumElements();
+
+      // For safety purposes lets add a constraint and only padd when
+      // num bytes to copy == destination array size == source string
+      // which is a constant
+      if (NumBytesToCopy != DZSize || DZSize != SZSize) {
+        continue;
+      }
+      unsigned int NumBytesToPad = 4 - (NumBytesToCopy % 4);
+      unsigned int TotalBytes = NumBytesToCopy + NumBytesToPad;
+
+      /*
----------------
davemgreen wrote:

Use //

https://github.com/llvm/llvm-project/pull/107120


More information about the llvm-commits mailing list