[llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Mon Mar 21 12:59:27 PST 2005
Changes in directory llvm-java/lib/Compiler:
Compiler.cpp updated: 1.239 -> 1.240
---
Log message:
Add String support. We finally have strings in the java frontend :-)
---
Diffs of the changes: (+110 -13)
Compiler.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 110 insertions(+), 13 deletions(-)
Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.239 llvm-java/lib/Compiler/Compiler.cpp:1.240
--- llvm-java/lib/Compiler/Compiler.cpp:1.239 Mon Mar 21 14:01:03 2005
+++ llvm-java/lib/Compiler/Compiler.cpp Mon Mar 21 14:59:16 2005
@@ -66,12 +66,14 @@
std::auto_ptr<BasicBlockBuilder> bbBuilder_;
std::list<BasicBlock*> bbWorkList_;
typedef std::map<BasicBlock*, unsigned> OpStackDepthMap;
- OpStackDepthMap opStackDepthMap_;
+ OpStackDepthMap opStackDepthMap_;
+ typedef std::map<std::string, GlobalVariable*> StringMap;
+ StringMap stringMap_;
BasicBlock* currentBB_;
Locals locals_;
OperandStack opStack_;
Function *getVtable_, *setVtable_, *throw_, *isInstanceOf_,
- *memset_;
+ *memcpy_, *memset_;
typedef SetVector<Function*> FunctionSet;
FunctionSet toCompileFunctions_;
@@ -161,6 +163,11 @@
isInstanceOf_ = module_.getOrInsertFunction(
"llvm_java_is_instance_of", Type::IntTy,
ObjectBaseRefTy, VTableBaseRefTy, NULL);
+ memcpy_ = module_.getOrInsertFunction(
+ "llvm.memcpy", Type::VoidTy,
+ PointerType::get(Type::SByteTy),
+ PointerType::get(Type::SByteTy),
+ Type::ULongTy, Type::UIntTy, NULL);
memset_ = module_.getOrInsertFunction(
"llvm.memset", Type::VoidTy,
PointerType::get(Type::SByteTy),
@@ -187,13 +194,103 @@
return false;
}
- /// Given a llvm::Java::Constant returns a llvm::Constant.
- llvm::Constant* getConstant(Constant* c) {
- if (dynamic_cast<ConstantString*>(c))
- // FIXME: should return a String object represeting this ConstantString
- return ConstantPointerNull::get(
- PointerType::get(
- getClassInfo(ClassFile::get("java/lang/String")).getType()));
+ template <typename InsertionPointTy>
+ Value* createNewString(const std::string& str, InsertionPointTy* ip) {
+ // Create a new byte[] object and initialize it with the
+ // contents of this string constant.
+ Value* count = ConstantUInt::get(Type::UIntTy, str.size());
+ Value* arrayRef = allocateArray(getPrimitiveArrayInfo(BYTE),
+ Type::SByteTy,
+ getPrimitiveArrayVTableInfo(BYTE),
+ count,
+ ip);
+ // Copy string data.
+ std::vector<Value*> indices;
+ indices.reserve(3);
+ indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
+ indices.push_back(ConstantUInt::get(Type::UIntTy, 2));
+ indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
+ Value* arrayData = new GetElementPtrInst(arrayRef, indices, TMP, ip);
+ llvm::Constant* init = ConstantArray::get(str);
+ GlobalVariable* chars = new GlobalVariable(
+ init->getType(),
+ true,
+ GlobalVariable::InternalLinkage,
+ init,
+ str + ".str",
+ &module_);
+
+ std::vector<Value*> params;
+ params.reserve(4);
+ params.clear();
+ params.push_back(arrayData);
+ params.push_back(ConstantExpr::getPtrPtrFromArrayPtr(chars));
+ params.push_back(new CastInst(count, Type::ULongTy, TMP, ip));
+ params.push_back(ConstantUInt::get(Type::UIntTy, 0));
+ new CallInst(memcpy_, params, "", ip);
+
+ // Get class information for java/lang/String.
+ const ClassFile* cf = ClassFile::get("java/lang/String");
+ const ClassInfo& ci = getClassInfo(cf);
+ const VTableInfo& vi = getVTableInfo(cf);
+
+ // Create a new java/lang/String object.
+ Value* objRef = allocateObject(ci, vi, ip);
+
+ // Initialize it: call java/lang/String/<init>(byte[],int)
+ Method* method = getMethod("java/lang/String/<init>([BI)V");
+ Function* function = getFunction(method);
+ scheduleFunction(function);
+
+ params.reserve(3);
+ params.clear();
+ params.push_back(new CastInst(objRef, ObjectBaseRefTy, TMP, ip));
+ params.push_back(new CastInst(arrayRef, ObjectBaseRefTy, TMP, ip));
+ params.push_back(ConstantSInt::get(Type::IntTy, 0));
+ new CallInst(function, params, "", ip);
+
+ return objRef;
+ }
+
+ Value* getConstantString(ConstantString* s) {
+ const std::string& str = s->getValue()->str();
+ StringMap::iterator it = stringMap_.find(str);
+ if (it == stringMap_.end()) {
+ // Create the global variable for the string.
+ const Type* StringRefTy = PointerType::get(
+ getClassInfo(ClassFile::get("java/lang/String")).getType());
+ GlobalVariable* stringGlobal = new GlobalVariable(
+ StringRefTy,
+ false,
+ GlobalVariable::ExternalLinkage,
+ llvm::Constant::getNullValue(StringRefTy),
+ str + ".java/lang/String",
+ &module_);
+
+ // Insert this new string into the map.
+ it = stringMap_.insert(it, std::make_pair(str, stringGlobal));
+
+ // Get the static initializer function and get its one and
+ // only basic block to add code to.
+ Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT,
+ Type::VoidTy, 0);
+ Instruction* I = hook->front().getTerminator();
+ assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!");
+
+ Value* newString = createNewString(str, I);
+
+ // Store the string reference to the global variable.
+ new StoreInst(newString, stringGlobal, I);
+ }
+
+ return new LoadInst(it->second, TMP, currentBB_);
+ }
+
+ /// Given a llvm::Java::Constant returns a Value
+ /// (java/lang/Strings are not llvm::Constants).
+ Value* getConstant(Constant* c) {
+ if (ConstantString* s = dynamic_cast<ConstantString*>(c))
+ return getConstantString(s);
else if (ConstantInteger* i = dynamic_cast<ConstantInteger*>(c))
return ConstantSInt::get(Type::IntTy, i->getValue());
else if (ConstantFloat* f = dynamic_cast<ConstantFloat*>(c))
@@ -1498,9 +1595,9 @@
// final fields with static initializers.
bool isConstant = field->isStatic();
llvm::Constant* init;
- if (ConstantValueAttribute* cv = field->getConstantValueAttribute())
- init =
- ConstantExpr::getCast(getConstant(cv->getValue()), globalTy);
+ if (field->getConstantValueAttribute() &&
+ dyn_cast<llvm::Constant>(getConstant(field->getConstantValueAttribute()->getValue())))
+ init = ConstantExpr::getCast(dyn_cast<llvm::Constant>(getConstant(field->getConstantValueAttribute()->getValue())), globalTy);
else {
init = llvm::Constant::getNullValue(globalTy);
isConstant = false;
@@ -2371,7 +2468,7 @@
void do_athrow() {
Value* objRef = pop(ObjectBaseRefTy);
- new CallInst(throw_, objRef, TMP, currentBB_);
+ new CallInst(throw_, objRef, "", currentBB_);
new UnreachableInst(currentBB_);
}
More information about the llvm-commits
mailing list