llvm 得到一个struct的value,通过type得出struct各个成员变量的内存排布(第二版弃用,第三版优化)

void RemoveStruct::structMemoryArrange(Type* val_ty, int actual_width, int &use_width, bool &flag) {
//  val_ty是struct type,actual_width是需要取地址的长度,use_width是该struct需要的内存排布总长度,flag是取地址的长度是否取到无意义的地址空间标志位,无意义时改为false
  int step_width = 1;
  int val_width;
  int struct_val_elements = val_ty->getStructNumElements();
  for (int i = 0; i < struct_val_elements; i++) {
    if (val_ty->getStructElementType(i)->isIntegerTy()) {
      val_width = val_ty->getStructElementType(i)->getIntegerBitWidth();
      while (use_width % val_width != 0) {
        use_width += step_width;
      }
      use_width += val_width;
      //outs() << "  " << use_width;
    } else if (val_ty->getStructElementType(i)->isArrayTy()) {
      if (val_ty->getStructElementType(i)->getArrayElementType()->isIntegerTy()) {
        for (int j = 0; j < val_ty->getStructElementType(i)->getArrayNumElements(); ++j) {
          val_width = val_ty->getStructElementType(i)->getArrayElementType()->getIntegerBitWidth();
          while (use_width % val_width != 0) {
            use_width += step_width;
          }
          use_width += val_width;
          //outs() << "  " << use_width;
        }
      } else if (val_ty->getStructElementType(i)->getArrayElementType()->isArrayTy()) {
        assert(0);//TODO
      } else if (val_ty->getStructElementType(i)->getArrayElementType()->isStructTy()) {
        assert(0);//TODO
      }

    } else if (val_ty->getStructElementType(i)->isStructTy()) {
      int align = 0;
      //  BieCastStructAlign()为了得到当前Struct变量的align大小,当之前的use_width可以整除此struct的align,该struct内存排布连续排布,当整除不了时,则需要补齐大小,补齐大小为 align - (use_width % align)
      BitCastStructAlign(val_ty->getStructElementType(i), align);
      if (use_width % align == 0) {
        structMemoryArrange(val_ty->getStructElementType(i), actual_width, use_width, flag);
      } else {
        if (actual_width >= use_width && actual_width < (use_width + align - (use_width % align))) {
          flag = false;
        }
        use_width += align - (use_width % align);
        structMemoryArrange(val_ty->getStructElementType(i), actual_width, use_width, flag);
      }
    } else {
      outs() << "This Type is not considered! " << val_ty->getStructElementType(i) << "\n";
      assert(0);
    }
  }
  //  为了结尾时的字节对齐
  int last = 0;
  BitCastStructAlign(val_ty, last);
  if (use_width % last != 0) {
    if (actual_width >= use_width && actual_width < (use_width + last - (use_width % last))) {
      flag = false;
    }
    use_width += last - (use_width % last);
  }
  //outs() << "  " << use_width;

}

void RemoveStruct::BitCastStructAlign(Type* val_ty, int &align) {
  int struct_val_elements = val_ty->getStructNumElements();
  for (int i = 0; i < struct_val_elements; i++) {
    if (val_ty->getStructElementType(i)->isIntegerTy()) {
      if (val_ty->getStructElementType(i)->getIntegerBitWidth() > align) {
        align = val_ty->getStructElementType(i)->getIntegerBitWidth(); }
    } else if (val_ty->getStructElementType(i)->isArrayTy()) {
      BitCastArrayAlign(val_ty->getStructElementType(i), align);
    } else if (val_ty->getStructElementType(i)->isStructTy()) {
      BitCastStructAlign(val_ty->getStructElementType(i), align);
    } else {
      outs() << "This Type is not considered! " << val_ty->getStructElementType(i) << "\n";
      assert(0);
    }
  }
}

void RemoveStruct::BitCastArrayAlign(Type* val_ty, int &align) {
  if (val_ty->getArrayElementType()->isIntegerTy()) {
    if (val_ty->getArrayElementType()->getIntegerBitWidth() > align) {
      align = val_ty->getArrayElementType()->getIntegerBitWidth();
    }
  } else if (val_ty->getArrayElementType()->isArrayTy()) {
    //  array
    BitCastArrayAlign(val_ty->getArrayElementType(), align);
  } else if (val_ty->getArrayElementType()->isStructTy()) {
    BitCastStructAlign(val_ty->getArrayElementType(), align);
  } else {
    outs() << "This Type is not considered! " << val_ty->getArrayElementType() << "\n";
    assert(0);
  }
}
### 回答1: LLVM编译器实战教程第二版是一本介绍LLVM编译器的实践指南,书中详细介绍了如何使用LLVM编译器来构建高性能的编译器、工具和应用程序。该书主要分为三个部分,分别是LLVM基础知识、编译器中的LLVM和工具中的LLVM。 在LLVM基础知识部分,作者首先介绍了LLVM的概念和架构,并详细讲解了LLVM中的IR表示和优化。然后,作者介绍了如何使用LLVM来构建一个简单的编译器,包括如何实现词法分析、语法分析和代码生成。最后,作者讨论了如何使用LLVM来实现一些高级特性,例如JIT编译和LLVM IR的交互式优化。 在编译器中的LLVM部分,作者分别介绍了如何使用LLVM来开发C、C++和Objective-C编译器。该部分还讲解了如何使用LLVM来实现静态分析、污点分析和动态分析,并提供了一些实际的案例来帮助读者更好地理解。 在工具中的LLVM部分,作者介绍了如何使用LLVM来构建一些实用的工具,例如调试器、反汇编器和符号化工具。该部分还讨论了如何使用LLVM来实现自定义的代码生成器和目标描述文件,以及如何使用LLVM来增强其他编程语言和环境中的编译器。 总之,LLVM编译器实战教程第二版是一本非常实用且系统的指南,它能够帮助读者深入了解LLVM编译器的内部机制和应用方法,并且可以作为开发高性能编译器和工具的参考书籍。 ### 回答2: LLVM编译器实战教程第二版是一本面向开发者的指南,它旨在引导读者了解LLVM编译器的内部运作机制,以及如何为其开发可扩展的前端和后端工具。该教程深入浅出地讲解了LLVM编译器的内部结构,包括词法分析、语法分析和代码生成等内容。同时该书提供了许多有关如何使用LLVM开发编译器的实用示例和应用案例,包括如何构建前端和后端的IR、如何使用全局优化和代码生成等。总之,LLVM编译器实战教程第二版是一本很好的LLVM编译器实践指南,它对于那些想要了解LLVM编译器内部的人、想要使用LLVM开发编译器的人或想要利用LLVM优化和代码生成技术的人,都是一本非常有价值的参考书籍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值